您遇到了跨域资源共享 (CORS) 协议。Mozilla 对 CORS 有一个很好的介绍。您正在创建一个跨域 XHR,并且要使调用成功,您需要进行一些小的更改,或者通过您自己的服务器代理请求来解决问题。
也就是说,我相信谷歌的“实验性”服务存在错误,在他们修复它之前你将无法让它工作。此外,IE9 及更早版本不支持 CORS;IE10 计划这样做。
服务器不允许的 HTTP 方法是 OPTIONS 方法。什么嘿?您指定了 HTTP GET,对吗?是的,你做到了。然而,CORS 协议要求浏览器在某些条件下“预检”请求。为了进行预检,浏览器向 URL 发送一个 OPTIONS 请求,以查看服务器是否允许您发出 GET 请求。在这种情况下,您的 dojo.xhrGet 调用在您的背后,正在向您的请求添加一个“X-Requested-With: XMLHTTPRequest”标头。发送像 X-Requested-With 这样的非标准标头是触发预检的“某些条件”之一。
幸运的是,您可以通过添加
headers:{'X-Requested-With': null},
到您的 xhrArgs 参数。
完成此操作后,您将发送有效的 CORS 请求。然而,根据我今天的经验,谷歌并没有正确地满足 CORS 请求。Google API 控制台中“API 访问”选项卡上“Web 应用程序的客户端 ID”下的一项设置是“JavaScript 来源”。在这里,您列出将发出这些跨域请求之一的任何网页的来源,例如https://example.com 。这是来自 Chrome 的错误报告:
XMLHttpRequest cannot load https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token={elided}.
Origin https://example.com is not allowed by Access-Control-Allow-Origin.
检查 Google 的响应标头显示他们根本没有发送 Access-Control-Allow-Origin。
就我而言,由于我几小时前刚刚创建了一个应用程序,也许谷歌还没有将“允许的来源”信息传播到系统;可能这个电话明天会起作用。或者,这只是这个实验性功能中的一个错误。
解决方法:我只是让我的 nginx 服务器代理对 Google 的请求。
location /userinfo {
proxy_pass https://www.googleapis.com/oauth2/v1/userinfo;
proxy_redirect default;
}
然后我将 xhrGet 发送到“/userinfo”,一切正常。
dojo.xhrGet({
url: '/userinfo',
handleAs: 'json',
headers:{'X-Requested-With': null}, //superfluous now
content: {alt: 'json', access_token: params.access_token}
}).then(...)