Google Picker API无法登录报错,部署后运行一段时间失效如何解决
问题根因
- 你使用的
gapi.auth授权接口已被Google正式下线:该旧接口近期被完全停止服务,原有授权请求的参数格式不再被Google授权服务器兼容,直接返回400请求格式错误,控制台抛出的ub未捕获异常就是旧接口调用失败导致的。 - 授权弹窗触发时机违规:你在
gapi.load的异步回调中调用弹窗授权逻辑,此时已经脱离了用户点击按钮的交互上下文,浏览器会判定为恶意弹窗直接拦截,就会出现窗口一闪而过的情况。
修复方案
- 替换旧的
gapi.auth授权逻辑为当前官方支持的Google Identity Services授权方式 - 把授权弹窗的触发放在用户点击按钮的同步执行流程中,避免触发浏览器弹窗拦截规则
- 调整Picker初始化时序,优先获取有效OAuth令牌后再加载渲染Picker组件
修改后代码示例
替换原有授权相关逻辑即可:
<!-- 引入新的GIS授权库 --> <script src="https://accounts.google.com/gsi/client"></script> <script type="text/javascript"> var developerKey = my_developer_key; var clientId = my_client_id; var appId = my_google_app_id; var scope = 'https://www.googleapis.com/auth/drive.file'; var pickerApiLoaded = false; var oauthToken; var tokenClient; // 初始化GIS授权客户端 function initTokenClient() { tokenClient = google.accounts.oauth2.initTokenClient({ client_id: clientId, scope: scope, callback: (tokenResponse) => { if (tokenResponse && tokenResponse.access_token) { oauthToken = tokenResponse.access_token; createPicker(); } }, }); // 预加载picker api gapi.load('picker', {'callback': () => {pickerApiLoaded = true}}); } // 按钮点击直接触发授权 function loadPicker() { oauthToken = null; $('#select_file').focus(function() { this.blur(); }); // 直接在用户点击上下文内触发授权弹窗,不会被拦截 tokenClient.requestAccessToken({prompt: ''}); } // create and render a picker object function createPicker() { if (pickerApiLoaded && oauthToken) { var folderID = my_folder_id; var view = new google.picker.DocsView().setIncludeFolders(true).setParent(folderID); var picker = new google.picker.PickerBuilder() .enableFeature(google.picker.Feature.NAV_HIDDEN) .setAppId(appId) .setOAuthToken(oauthToken) .addView(view) .setDeveloperKey(developerKey) .setCallback(pickerCallback) .build(); picker.setVisible(true); } } // 原有Picker回调逻辑不变 function pickerCallback(data) { if (data.action == google.picker.Action.PICKED) { var fileName = data.docs[0].name; var fileID = data.docs[0].id; $('#fileName').val(fileName); $('#fileID').val(fileID); $('#file').text('File selected: ' + fileName); } validateForm() } // 页面加载完成后初始化授权客户端 window.onload = initTokenClient; </script>
按钮逻辑保持不变即可:
<input id="select_file" onClick="loadPicker(); return false;" value="Select File" class="btn">
内容的提问来源于stack exchange,提问作者Casey
相关产品推荐
相关产品推荐

