web-dev-qa-db-ja.com

gapiが定義されていない-gapi.auth2.initでのGoogleサインインの問題

Googleサインインを実装し、ユーザーのプロファイル情報を取得しようとしています。エラー:Uncaught ReferenceError:gapi is not defined。何故ですか?

<!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>
28
Jon Tan

スクリプトタグにasyncおよびdefer属性があるために発生します。 gapiは、スクリプトタグの後にgapi.auth2.init...

このコードを実行する前にgapiを待つには、次のようにスクリプトタグでonload query paramを使用できます。

<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>

または、多くの場所で必要な場合は、promiseを使用してより適切に構造化できます。

// 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
  });
});
42
Bogdan Savluk

上記の例では、gapi.auth2がまだ定義されていないため、これも機能しないことがわかると思います(今日、同じ間違いを犯したため、これを知っています)最初にgapi.load('auth2', callback)そして、コールバックをTHATに渡してから、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()
  })
}

その後、_auth2変数を使用して、実際にユーザーをサインインできます。

11
Kelly Ellis

問題はgapiだけではありません。 initメソッドを呼び出すには、auth2オブジェクトを初期化する必要があります。 Google認証オブジェクトが完全に初期化されると、約束があります 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
    });
}
9
bora89

これらの答えは私を助けましたが、公式ドキュメントにはより良い答えがあると思います。

リスナーを使用した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();
  }
}
3
Miha Pirnat

これは私のために働いた: https://stackoverflow.com/a/55314602/1034622

このスクリプトタグを含める

<script src="https://apis.google.com/js/platform.js"></script>
0
Pablo Chvx