Google 选择器身份验证弹出窗口被阻止

Google picker auth popup is being blocked(Google 选择器身份验证弹出窗口被阻止)
本文介绍了Google 选择器身份验证弹出窗口被阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列出工作的移动网站,用户申请并上传他们的简历(简历) - 我希望他们能够从他们的 Google Drive 中选择一个文件.

I have a mobile site which lists jobs, the user applies and uploads their CV (resume) - I want them to be able to choose a file from their Google Drive.

我在这里创建了 Hello world 示例 - https://developers.google.com/picker/docs/(为方便起见,此处复制代码)

I've created the Hello world example here - https://developers.google.com/picker/docs/ (code reproduced here for convenience)

问题是,如果尚未登录云端硬盘,则会启动一个登录弹出窗口.这在台式机上已经够糟糕了,但在手机上真的很糟糕.

Problem is that if not already logged into Drive, a popup to login is launched. This is bad enough on a desktop but really bad on a phone.

我已尝试此解决方案,但得到TypeError:gapi.auth 未定义'

I have tried this solution, but get 'TypeError: gapi.auth is undefined'

我还尝试从 onclick 事件而不是文档中描述的 onload 启动选择器.

I also tried launching the picker from an onclick event rather than the onload as described by the docs.

function launchDrive()
    {
        gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.load('picker', {'callback': onPickerApiLoad});
    }
<input type='button' value='Launch Drive' onclick='launchDrive();'>

Google 代码示例:

Sample Google code:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Picker Example</title>

    <script type="text/javascript">

      var developerKey = 'xxxxxxxYYYYYYYY-12345678';
      var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
      var scope = ['https://www.googleapis.com/auth/photos'];

      var pickerApiLoaded = false;
      var oauthToken;

      function onApiLoad() {
        gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.load('picker', {'callback': onPickerApiLoad});
      }

      function onAuthApiLoad() {
        window.gapi.auth.authorize(
            {
              'client_id': clientId,
              'scope': scope,
              'immediate': false
            },
            handleAuthResult);
      }

      function onPickerApiLoad() {
        pickerApiLoaded = true;
        createPicker();
      }

      function handleAuthResult(authResult) {
        if (authResult && !authResult.error) {
          oauthToken = authResult.access_token;
          createPicker();
        }
      }

      // Create and render a Picker object for picking user Photos.
      function createPicker() {
        if (pickerApiLoaded && oauthToken) {
          var picker = new google.picker.PickerBuilder().
              addView(google.picker.ViewId.PHOTOS).
              setOAuthToken(oauthToken).
              setDeveloperKey(developerKey).
              setCallback(pickerCallback).
              build();
          picker.setVisible(true);
        }
      }

      // A simple callback implementation.
      function pickerCallback(data) {
        var url = 'nothing';
        if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
          var doc = data[google.picker.Response.DOCUMENTS][0];
          url = doc[google.picker.Document.URL];
        }
        var message = 'You picked: ' + url;
        document.getElementById('result').innerHTML = message;
      }
    </script>
  </head>
  <body>
    <div id="result"></div>

    <!-- The Google API Loader script. -->
    <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
  </body>
</html>

2015 年 5 月 13 日编辑

除了杰森的回答,这也是我尝试过的(由 oncllick 按钮调用):

Further to Jason's answer, here is what I also tried (called by a button oncllick):

function launchDrive()
    {
        //gapi.load('auth', {'callback': onAuthApiLoad});
        gapi.auth.init(onAuthApiLoad);
        gapi.load('picker', {'callback': onPickerApiLoad});
    }

推荐答案

要解决您的问题,您需要了解 google 如何在您的案例中执行 oauth:

To solve your issue you need to understand how google performs oauth in your case:

  • gapi 执行初始化操作
  • gapi 在新的弹出窗口中打开一个 google auth 页面,您在其中执行登录
  • 登录成功后,gapi 会收到通知并收到您的令牌

为什么浏览器会在第二步中阻止弹出窗口:

Why browser blocks the popup in 2nd step:

  • 窗口中不再存在原始事件(window.event 已销毁).
  • 用户手动阻止了当前站点的弹出窗口

因此,如果用户没有阻止弹出窗口并且您的弹出窗口仍然被阻止,gapi 操作看起来像:

So if user didn't block a popup and you popup is still blocked, gapi actions look something like:

<input type="button" onclick="auth" value="click"/>

function auth() {
  setTimeout(function() {
     // by this time window.event is destroyed, that's why browser blocks the popup
     window.open(document.URL, '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');
  }, 100)
}

那么你应该怎么做:

  • 确保在单击按钮后,您不会执行任何异步操作,例如 XHRequests 或其他
  • 确保在用户单击按钮时已启动并准备好 gapi,因此当 gapi 需要创建弹出窗口时,window.event 不会为空.所以将所有 gapi init 方法移动到 DOMContentLoaded.
  • 作为另一种选择,您可以使用服务器端 oauth 流,这意味着用户将在当前选项卡中重定向到 gauth 页面,而不是弹出用户.
  • Make sure that after button click you don't perform any asynchronous actions like XHRequests or other
  • Make sure gapi is inited and ready by the time users click on the button, so by the time gapi needs to create a popup, window.event won't be null. So move all gapi init methods to DOMContentLoaded.
  • As another option you could use server-side oauth flow, which means instead of popup user will be redirected in current tab to gauth page.

这篇关于Google 选择器身份验证弹出窗口被阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)