Estoy tratando de implementar el inicio de sesión de Google y recuperar la información del perfil del usuario. El error es: Error de referencia no capturado: gapi no está definido. ¿Porqué es eso?
<!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>Ocurre porque tiene atributos async y defer en su etiqueta de secuencia de comandos. gapi se cargaría después de su etiqueta de secuencia de comandos con gapi.auth2.init ...
Para esperar a gapi antes de ejecutar este código, puede usar el parámetro de consulta onload en la etiqueta del script, como se muestra a continuación:
<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>O, en caso de que lo necesite en muchos lugares, puede usar promesas para estructurarlo mejor:
// 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 }); });Creo que encontrará con el ejemplo anterior que esto tampoco funcionará, ya que gapi.auth2 aún no se definirá (lo sé porque yo mismo cometí el mismo error hoy). Primero debe llamar a gapi.load('auth2', callback) y pase ESO una devolución de llamada que luego llama a gapi.auth2.init . Este es un ejemplo de mi función _onGoogleLoad , que es la devolución de llamada para cargar el primer script de 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() }) } Después de eso, puede usar la variable _auth2 para iniciar sesión de los usuarios.
El problema no está solo en gapi . Para llamar al método init , el objeto auth2 debe estar inicializado. Hay una promesa una vez que un objeto de autenticación de Google está en GoogleAuth.then completamente inicializado 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 }); }