猿问

在 Angular 中使用 Google One Tap

我想在我的 Angular 11 应用程序中使用 Google One Tap。按照文档,我添加<script async defer src="https://accounts.google.com/gsi/client"></script>到我的 html 中,然后在我的 中使用以下代码app.component.html

<div id="g_id_onload"
    data-client_id="MY_GOOGLE_CLIENT_ID"
    data-callback="handleCredentialResponse",
    data-cancel_on_tap_outside="false">
</div>

弹出窗口工作正常,但我似乎无法登录。如果我handleCredentialResponse在 中创建一个函数app.component.ts,则会收到以下错误:[GSI_LOGGER]: The value of 'callback' is not a function. Configuration ignored.

如果我尝试使用 JavaScript API,Typescript 会抛出以下错误:Property 'accounts' does not exist on type 'typeof google'

我应该怎么做才能在 Angular 中使用 Google One Tap?


繁花不似锦
浏览 164回答 4
4回答

人到中年有点甜

当我使用 HTML API 方法时,我遇到了类似的问题,所以我最终使用了JavaScript API。这就是我所做的:首先,确保安装@types/google-one-tap软件包。正如您所提到的,我还将脚本导入到我的index.html文件中,如下所示:<body>   <script src="https://accounts.google.com/gsi/client" async defer></script>   <app-root>   </app-root></body>现在,继续讨论您的主要组件,在我的例子中是app.component.ts,首先导入以下内容:import { CredentialResponse, PromptMomentNotification } from 'google-one-tap';然后,您可以将其添加到ngOnInit(). 请务必阅读文档以获取有关onGoogleLibraryLoad事件的更多详细信息:// @ts-ignorewindow.onGoogleLibraryLoad = () => {  console.log('Google\'s One-tap sign in script loaded!');  // @ts-ignore  google.accounts.id.initialize({    // Ref: https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration    client_id: 'XXXXXXXX',    callback: this.handleCredentialResponse.bind(this), // Whatever function you want to trigger...    auto_select: true,    cancel_on_tap_outside: false  });  // OPTIONAL: In my case I want to redirect the user to an specific path.  // @ts-ignore  google.accounts.id.prompt((notification: PromptMomentNotification) => {    console.log('Google prompt event triggered...');    if (notification.getDismissedReason() === 'credential_returned') {      this.ngZone.run(() => {        this.router.navigate(['myapp/somewhere'], { replaceUrl: true });        console.log('Welcome back!');      });    }  });};然后,该handleCredentialResponse函数是您使用用户凭据处理实际响应的地方。就我而言,我想先对其进行解码。查看此内容以获取有关凭证解码后的外观的更多详细信息: https: //developers.google.com/identity/gsi/web/reference/js-reference#credential// @ts-ignorewindow.onGoogleLibraryLoad = () => {  console.log('Google\'s One-tap sign in script loaded!');  // @ts-ignore  google.accounts.id.initialize({    // Ref: https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration    client_id: 'XXXXXXXX',    callback: this.handleCredentialResponse.bind(this), // Whatever function you want to trigger...    auto_select: true,    cancel_on_tap_outside: false  });  // OPTIONAL: In my case I want to redirect the user to an specific path.  // @ts-ignore  google.accounts.id.prompt((notification: PromptMomentNotification) => {    console.log('Google prompt event triggered...');    if (notification.getDismissedReason() === 'credential_returned') {      this.ngZone.run(() => {        this.router.navigate(['myapp/somewhere'], { replaceUrl: true });        console.log('Welcome back!');      });    }  });};

ABOUTYOU

设置模板中的div在ngOnInit中渲染&nbsp; &nbsp; `<div id="loginBtn" > </div>`在您的login.ts中动态注入脚本标签,如下所示constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document: Document){}ngAfterViewInit() {&nbsp; &nbsp; &nbsp; &nbsp; const script1 = this._renderer2.createElement('script');&nbsp; &nbsp; &nbsp; &nbsp; script1.src = `https://accounts.google.com/gsi/client`;&nbsp; &nbsp; &nbsp; &nbsp; script1.async = `true`;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; script1.defer = `true`;&nbsp;&nbsp; &nbsp; this._renderer2.appendChild(this._document.body, script1);&nbsp; }ngOnInit(): void {&nbsp;&nbsp; &nbsp; // @ts-ignore&nbsp; &nbsp; window.onGoogleLibraryLoad = () => {&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; // @ts-ignore&nbsp; &nbsp; &nbsp; google.accounts.id.initialize({&nbsp; &nbsp; &nbsp; &nbsp; client_id: '335422918527-fd2d9vpim8fpvbcgbv19aiv98hjmo7c5.apps.googleusercontent.com',&nbsp; &nbsp; &nbsp; &nbsp; callback: this.googleResponse.bind(this),&nbsp; &nbsp; &nbsp; &nbsp; auto_select: false,&nbsp; &nbsp; &nbsp; &nbsp; cancel_on_tap_outside: true,&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; // @ts-ignore&nbsp; &nbsp; &nbsp; google.accounts!.id.renderButton( document!.getElementById('loginBtn')!, { theme: 'outline', size: 'large', width: 200 } )&nbsp; &nbsp; &nbsp; // @ts-ignore&nbsp; &nbsp; &nbsp; google.accounts.id.prompt();&nbsp;&nbsp; &nbsp; }&nbsp; }async googleResponse(response: google.CredentialResponse) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // your logic goes here}

PIPIONE

我在将函数添加到角度分量时也遇到了同样的问题。然后我找到了一个解决方案,通过添加 JS 函数,appComponent如下所示:(window as any).handleCredentialResponse = (response) => {&nbsp; &nbsp; &nbsp; /* your code here for handling response.credential */}

肥皂起泡泡

Google One Tap js 库尝试在全局范围内查找callback,但找不到它,因为您的callback函数的范围位于应用程序内部的某个位置,因此您可以将回调附加到 window,&nbsp;like window.callback = function(data) {...}。另外,由于您将其附加到窗口,因此最好为该函数指定一个不太通用的名称。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答