【问题标题】:`Uncaught TypeError: Cannot read property 'signOut' of undefined``未捕获的类型错误:无法读取未定义的属性'signOut'`
【发布时间】:2021-09-26 13:49:05
【问题描述】:

我得到错误:

未捕获的类型错误:无法读取未定义的属性“signOut”

在这条线上:auth2.signOut()

我在下面的页面上没有 google 登录按钮。 我也尝试过执行函数signOutGoogle,但这也会导致错误。

我在<head>的页面置顶:

<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com">

&lt;/body&gt; 标签之前我有:

<script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>

JavaScript 代码:

function onLoad() {
    console.error('onLoad executed.');
    var auth2;
    gapi.load('auth2', function () {
        auth2 = gapi.auth2.init({
           client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
        });
        auth2 = gapi.auth2.getAuthInstance();
    });  
           
    //check if url contains ?signout=true
    var url = window.location.href;
    if (url.toString().indexOf('?signout=true') != -1) {
        console.error('param found');

        auth2.signOut().then(function () {
            console.error('User signed out');
        });
    }
}

更新 1

由于某种原因 ga 被调用(我自己并没有明确地这样做)并且失败了,这里发生了什么?

我已经在这里检查过:

更新 2

现在我遇到错误

未捕获的错误:ia

更新 3

我尝试从脚本调用中删除调用 noload,然后将其添加到 document.ready 以调用 signout 函数,但即使使用 @Vishal 的代码,API 仍然不可用:

&lt;script src="https://apis.google.com/js/platform.js"&gt;&lt;/script&gt;&lt;/body&gt;

还有:

    $(document).ready(function () {
        var url = window.location.href;
        if (url.toString().indexOf('?signout=true') != -1) {
            console.error('onLoad executed.');
            var auth2;
            gapi.load('auth2', function () {
                auth2 = gapi.auth2.init({
                    client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
                }).then(() => {
                    auth2 = gapi.auth2.getAuthInstance();
                    auth2.signOut().then(function () {
                        console.error('User signed out');
                    });
                }).catch(err => {
                    console.log(err);
                });
            });
        }
    });

【问题讨论】:

    标签: javascript google-signin


    【解决方案1】:

    您的 javascript 代码应该如下所示,并且在代码中,我在 init 操作的 then() 部分添加了注销执行。因此,只有在 init 返回并收到来自服务器的响应后,才会执行注销代码。

    function onLoad() {
        console.error('onLoad executed.');
        var auth2;
        gapi.load('auth2', function () {
            auth2 = gapi.auth2.init({
               client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
            }).then(() => {
               auth2 = gapi.auth2.getAuthInstance();
               //check if url contains ?signout=true
               var url = window.location.href;
               if (url.toString().indexOf('?signout=true') != -1) {
                  console.error('param found');
    
                  auth2.signOut().then(function () {
                       console.error('User signed out');
                  });
                }
             }).catch(err => {
                 console.log(err);
             });
            
        });
    }
    

    【讨论】:

    • 完美!太感谢了!一个小的后续问题:你知道为什么我登录后从不退出并在一天后返回同一页面,我仍然登录吗? Google 不会在 X 小时后自动使会话过期吗?如果没有,有没有办法自己做到这一点?
    • @Flo 感谢您的支持,实际上您在脚本标签中使用了 onload=onLoad,因此它始终会首先启动会话,并在找到匹配的 URL 时注销用户。因此,当用户单击登录操作时,您可能需要调用 onLoad 函数,这可能应该是应用程序中的一个按钮,因此 init 将在页面加载时执行一次,而不是每次都执行。
    • 当然,我想我们快到了 :) 请检查我的更新 3,因为当不使用 onload 检查并且不想每次都执行 onload 时,Google 的 API 的可用性成为一个问题再次。你能帮忙吗?
    • 友好碰撞
    • @Flo 是的,好吗?我正在检查你在上一条评论中提到的问题,所以会在这里更新给你。
    【解决方案2】:
      function onLoad() {
        console.error("onLoad executed.");
        var auth2;
    
        const oauthLogin = new Promise((resolve, reject) => {
          gapi.load("auth2", function () {
            auth2 = gapi.auth2.init({
              client_id: "MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com",
            });
            auth2 = gapi.auth2.getAuthInstance();
          });
        });
    
        oauthLogin.then(() => {
          if (window.location.href.indexOf("?signout=true") != -1) {
            console.error("param found");
            auth2.signOut().then(function () {
              console.error("User signed out");
            });
          }
        });
      }
    

    你可以给一个变量分配一个promise,并在它像这样解析之后执行一些代码。 有多种方法可以实现,请查看Promise.prototype.then() 参考。

    顺便说一句,您不需要将 window.location.href 解析为 String,因为它 location.href 是一个字符串化器,它返回适合您目的的 USVString。

    【讨论】:

      【解决方案3】:

      您的问题很可能是您的代码在定义auth2 变量之前调用了signOut 函数。根据您的代码,来自gapi.load 的回调不会立即执行,并且由于 JavaScript 已编译,

      var url = window.location.href;
      if (url.toString().indexOf('?signout=true') != -1) {
          console.error('param found');
      
          auth2.signOut().then(function () {
          console.error('User signed out');
          });
      }
      

      auth2 仍然是undefined 时,您的部分代码正在被调用。试着把它放在你的回调中,像这样:

      function onLoad() {
          console.error('onLoad executed.');
          var auth2;
          gapi.load('auth2', function () {
              auth2 = gapi.auth2.init({
                 client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
              });
              auth2 = gapi.auth2.getAuthInstance();
                 
              //check if url contains ?signout=true
              var url = window.location.href;
              if (url.toString().indexOf('?signout=true') != -1) {
                  console.error('param found');
      
                  auth2.signOut().then(function () {
                      console.error('User signed out');
                  });
              }
          });
      }
      

      【讨论】:

      • 不幸的是,我仍然得到与上面截图中相同的 Uncaught Error: ga 错误
      • 是在使用signOutGoogle函数的时候吗?它尝试使用auth2 变量,该变量在onLoad 函数中定义,因此无法使用。
      • 实际上不,我从未调用过的整个函数,为了清楚起见,我从帖子中删除了它。我添加了更新 2,现在我得到 ia 未定义。它与at qx.a.&lt;computed&gt; [as signOut] (cb=gapi.loaded_0?le=ili,ipu:339) 相关,所以它看起来像谷歌库中的一个函数,但我不知道这个注销函数在哪里(onLoad 除外)被调用...
      猜你喜欢
      • 1970-01-01
      • 2021-12-22
      • 2015-01-06
      • 2017-07-26
      • 2019-02-26
      • 2021-12-25
      • 1970-01-01
      相关资源
      最近更新 更多