Vue中实现Google Calendar API GIS认证报错,请求协助修复
问题修复方案
错误原因
- 全局函数未定义:index.html中
onload="initClient()"调用的是全局函数,但你的initClient是Vue组件内部的方法,全局作用域无法找到,导致client从未被初始化,调用getToken时自然会出现client为undefined的错误。 - 变量作用域问题:全局变量
client和access_token不符合Vue组件化规范,容易引发作用域混乱。 - 脚本加载时机不匹配:GIS脚本是异步加载的,可能在Vue组件初始化完成前还未加载完成,直接调用
google对象会出错。
修复步骤
1. 修改index.html中的GIS脚本标签
移除无效的onload调用,确保脚本异步加载即可:
<script src="https://accounts.google.com/gsi/client" async defer></script>
2. 调整Vue组件代码
将变量移到组件data中,在mounted钩子中等待GIS脚本加载完成后初始化客户端,同时完善错误处理:
<template> <h1>Google Identity Services Authorization Token model</h1> <button @click="getToken()">Get access token</button><br><br> <button @click="loadCalendar()">Load Calendar</button><br><br> <button @click="revokeToken()">Revoke token</button> </template> <script> export default { data() { return { client: null, access_token: null } }, mounted() { // 轮询等待Google GIS脚本加载完成 const checkInterval = setInterval(() => { if (window.google?.accounts?.oauth2) { clearInterval(checkInterval); this.initClient(); } }, 100); }, methods: { initClient() { this.client = window.google.accounts.oauth2.initTokenClient({ client_id: '你的客户端ID', // 替换为实际的Client ID scope: 'https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/contacts.readonly', callback: (tokenResponse) => { this.access_token = tokenResponse.access_token; }, }); }, getToken() { if (!this.client) { console.error('客户端尚未初始化,请等待脚本加载完成'); return; } this.client.requestAccessToken(); }, revokeToken() { if (!this.access_token || !window.google?.accounts?.oauth2) { console.error('无可用的access token或GIS脚本未加载'); return; } window.google.accounts.oauth2.revoke(this.access_token, () => { console.log('access token revoked'); this.access_token = null; // 重置token状态 }); }, loadCalendar() { if (!this.access_token) { console.error('请先获取access token'); return; } const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events'); xhr.setRequestHeader('Authorization', 'Bearer ' + this.access_token); // 添加请求结果处理 xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { console.log('日历数据:', JSON.parse(xhr.responseText)); } else { console.error('加载日历失败:', xhr.statusText); } }; xhr.send(); } } } </script>
关键优化点
- 使用Vue组件的
data属性管理client和access_token,符合组件化开发规范,避免全局变量污染。 - 通过轮询确保GIS脚本加载完成后再初始化客户端,解决异步加载导致的对象未定义问题。
- 在各个方法中增加空值判断,提前拦截错误并给出提示。
内容的提问来源于stack exchange,提问作者Steven Diffey
相关产品推荐
相关产品推荐

