Подтвердить что ты не робот

Gapi не определен - Google подписывает вопрос с gapi.auth2.init

Я пытаюсь внедрить Google Sign In и получать информацию о профиле пользователя. Ошибка: Uncaught 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>
4b9b3361

Ответ 1

Это происходит потому, что у вас есть атрибуты async и defer в тэге script. gapi будет загружен после тэга script с помощью gapi.auth2.init...

Чтобы дождаться gapi перед выполнением этого кода, вы можете использовать параметр запроса onload в теге script, например:

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

Или для случая, когда вам это нужно во многих местах, вы можете использовать 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
  });
});

Ответ 2

Я думаю, вы найдете в приведенном выше примере, что это тоже не сработает, так как gapi.auth2 пока не будет определен (я знаю это, потому что сам сделал ту же ошибку сегодня). Сначала вам нужно позвонить gapi.load('auth2', callback) и передать THAT обратный вызов, который затем вызывает gapi.auth2.init. Ниже приведен пример моей функции _onGoogleLoad, которая является обратным вызовом для загрузки первого platform.js script.

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, чтобы фактически подписывать пользователей.

Ответ 3

Проблема не только в 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
    });
}

Ответ 4

Хотя эти ответы помогли мне, я считаю, что в официальных документах есть лучший ответ.

См. Интеграция входа в 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();
  }
}

Ответ 5

Это сработало для меня: fooobar.com/info/17154596/...

Включить этот тег сценария

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