web-dev-qa-db-fra.com

gapi n'est pas défini - Google signe en problème avec gapi.auth2.init

J'essaie de mettre en œuvre Google Sign In et de récupérer les informations de profil de l'utilisateur. L'erreur est la suivante: Uncaught ReferenceError: gapi n'est pas défini. Pourquoi donc?

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

Cela se produit parce que vous avez les attributs async et defer sur votre balise de script. gapi serait chargé après votre balise de script avec gapi.auth2.init...

Pour attendre gapi avant d'exécuter ce code, vous pouvez utiliser le paramètre de requête onload dans une balise de script, comme suit:

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

Ou au cas où vous en auriez besoin à plusieurs endroits, vous pouvez utiliser les promesses pour mieux la structurer:

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

Je pense que vous constaterez avec l'exemple ci-dessus que cela ne fonctionnera pas non plus, car gapi.auth2 Ne sera pas encore défini (je le sais parce que j'ai moi-même commis la même erreur, aujourd'hui). Vous devez d'abord appeler gapi.load('auth2', callback) et transmettez CELA un rappel qui appelle ensuite gapi.auth2.init. Voici un exemple de ma fonction _onGoogleLoad, Qui est le rappel pour charger le premier script 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()
  })
}

Après cela, vous pouvez utiliser la variable _auth2 Pour connecter les utilisateurs.

11
Kelly Ellis

Le problème n'est pas seulement dans gapi. Pour appeler init method - un objet auth2 doit être initialisé. Il y a une promesse une fois qu'un objet google auth est complètement initialisé 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

Bien que ces réponses m'ont aidé, je pense qu'il existe une meilleure réponse dans les documents officiels.

Voir Intégration de Google Sign-In à l'aide de listeners

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

Cela a fonctionné pour moi: https://stackoverflow.com/a/55314602/1034622

Inclure cette balise de script

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