gapi未定义 - 谷歌与gapi.auth2.init签订了问题

Jon*_*Tan 30 javascript google-signin

我正在尝试实施Google登录并检索用户的个人资料信息.错误是:未捕获的ReferenceError:未定义gapi.这是为什么?

<!doctype html>
<html>
<head>      
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
    <script type="text/javascript">
    $(function(){
        gapi.auth2.init({
            client_id: 'filler_text_for_client_id.apps.googleusercontent.com'
        });
    });
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Bog*_*luk 43

这是因为你asyncdefer你的脚本标记属性.gapi将在脚本标记后加载gapi.auth2.init...

gapi在执行此代码之前等待,您可以在脚本标记中使用onload查询参数,如下所示:

<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script>
<script>
window.onLoadCallback = function(){
  gapi.auth2.init({
      client_id: 'filler_text_for_client_id.apps.googleusercontent.com'
    });
}
</script>
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要在许多地方使用它,您可以使用promises来更好地构建它:

// promise that would be resolved when gapi would be loaded
var gapiPromise = (function(){
  var deferred = $.Deferred();
  window.onLoadCallback = function(){
    deferred.resolve(gapi);
  };
  return deferred.promise()
}());

var authInited = gapiPromise.then(function(){
  gapi.auth2.init({
      client_id: 'filler_text_for_client_id.apps.googleusercontent.com'
    });
})


$('#btn').click(function(){
  gapiPromise.then(function(){
    // will be executed after gapi is loaded
  });

  authInited.then(function(){
    // will be executed after gapi is loaded, and gapi.auth2.init was called
  });
});
Run Code Online (Sandbox Code Playgroud)


Kel*_*lis 12

我想你会发现上面的例子,这也不会起作用,因为gapi.auth2还没有定义(我知道这是因为我自己犯了同样的错误,今天)你首先需要调用gapi.load('auth2', callback)并传递一个回调然后回调电话gapi.auth2.init.这是我的_onGoogleLoad函数的一个例子,它是加载第一个platform.js脚本的回调.

var _auth2

var _onGoogleLoad = function () {
  gapi.load('auth2', function () {
    _auth2 = gapi.auth2.init({
      client_id: 'OUR_REAL_ID_GOES_HERE',
      scope: 'email',
      fetch_basic_profile: false
    })
    _enableGoogleButton()
  })
}
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用该_auth2变量实际签署用户.


bor*_*a89 9

问题不仅在于gapi.要调用init方法 - 必须初始化auth2对象.一旦google auth对象完全初始化,就会有一个承诺GoogleAuth.then(onInit, onFailure)

gapi.load('auth2', initSigninV2);

function initSigninV2() {
    gapi.auth2.init({
        client_id: 'CLIENT_ID.apps.googleusercontent.com'
    }).then(function (authInstance) {
        // now auth2 is fully initialized
    });
}
Run Code Online (Sandbox Code Playgroud)


Mih*_*nat 6

虽然这些答案对我有所帮助,但我相信官方文档中有更好的答案。

请参阅使用侦听器集成 Google 登录

var auth2; // The Sign-In object.
var googleUser; // The current user.

/**
 * Calls startAuth after Sign in V2 finishes setting up.
 */
var appStart = function() {
  gapi.load('auth2', initSigninV2);
};

/**
 * Initializes Signin v2 and sets up listeners.
 */
var initSigninV2 = function() {
  auth2 = gapi.auth2.init({
      client_id: 'CLIENT_ID.apps.googleusercontent.com',
      scope: 'profile'
  });

  // Listen for sign-in state changes.
  auth2.isSignedIn.listen(signinChanged);

  // Listen for changes to current user.
  auth2.currentUser.listen(userChanged);

  // Sign in the user if they are currently signed in.
  if (auth2.isSignedIn.get() == true) {
    auth2.signIn();
  }

  // Start with the current live values.
  refreshValues();
};

/**
 * Listener method for sign-out live value.
 *
 * @param {boolean} val the updated signed out state.
 */
var signinChanged = function (val) {
  console.log('Signin state changed to ', val);
  document.getElementById('signed-in-cell').innerText = val;
};

/**
 * Listener method for when the user changes.
 *
 * @param {GoogleUser} user the updated user.
 */
var userChanged = function (user) {
  console.log('User now: ', user);
  googleUser = user;
  updateGoogleUser();
  document.getElementById('curr-user-cell').innerText =
    JSON.stringify(user, undefined, 2);
};

/**
 * Updates the properties in the Google User table using the current user.
 */
var updateGoogleUser = function () {
  if (googleUser) {
    document.getElementById('user-id').innerText = googleUser.getId();
    document.getElementById('user-scopes').innerText =
      googleUser.getGrantedScopes();
    document.getElementById('auth-response').innerText =
      JSON.stringify(googleUser.getAuthResponse(), undefined, 2);
  } else {
    document.getElementById('user-id').innerText = '--';
    document.getElementById('user-scopes').innerText = '--';
    document.getElementById('auth-response').innerText = '--';
  }
};

/**
 * Retrieves the current user and signed in states from the GoogleAuth
 * object.
 */
var refreshValues = function() {
  if (auth2){
    console.log('Refreshing values...');

    googleUser = auth2.currentUser.get();

    document.getElementById('curr-user-cell').innerText =
      JSON.stringify(googleUser, undefined, 2);
    document.getElementById('signed-in-cell').innerText =
      auth2.isSignedIn.get();

    updateGoogleUser();
  }
}
Run Code Online (Sandbox Code Playgroud)


cou*_*ing 5

对于 Vue.JS 应用程序

  • 将 onload 钩子添加到脚本标记中platform.js
  • 设置一个调度事件的函数
  • mounted在组件的钩子中捕获该事件。

这是一个相当完整的示例,您可以将其粘贴到新vue-cli项目中。

不要忘记提供您自己的客户 ID!

公共/index.html

    <script type="text/javascript">
      function triggerGoogleLoaded() {
        window.dispatchEvent(new Event("google-loaded"));
      }
    </script>
    <script
      src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded"
      async
      defer
    ></script>
    <meta
      name="google-signin-client_id"
      content="xxxxxxxxxxxx.apps.googleusercontent.com"
    />

Run Code Online (Sandbox Code Playgroud)

应用程序.vue

<template>
  <div id="app">
    <div id="nav">
      <div id="google-signin-btn"></div>
      <a href="#" class="sign-out" @click="signOut" v-if="profile">Sign out</a>
    </div>
    <div v-if="profile" class="">
      <h2>Signed In User Profile</h2>
      <pre>{{ profile }}</pre>
    </div>
    <div v-if="!profile">
      <h2>Signed out.</h2>
    </div>
    <router-view />
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      profile: false
    };
  },
  methods: {
    onSignIn(user) {
      const profile = user.getBasicProfile();
      this.profile = profile;
    },
    signOut() {
      var auth2 = gapi.auth2.getAuthInstance();
      auth2.signOut().then(() => {
        location.reload(true);
      });
    },
    renderGoogleLoginButton() {
      gapi.signin2.render("google-signin-btn", {
        onsuccess: this.onSignIn
      });
    }
  },
  mounted() {
    window.addEventListener("google-loaded", this.renderGoogleLoginButton);
  }
};
</script>


Run Code Online (Sandbox Code Playgroud)