您已针对跨源资源共享(CORS)协议运行。 Mozilla has a nice intro to CORS。您正在创建一个跨源XHR,并且为了成功完成调用,您需要做一些小改动,或者通过代理通过您自己的服务器请求解决方法。
这就是说,我认为Google仍然存在“实验性”服务中的错误,并且在解决此问题之前,您无法将其解决。此外,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请求。然而,就我今天的经验来看,Google没有正确地履行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尚未将“允许的来源”信息传播给系统;可能这个电话会在明天工作。或者,这只是这个实验性功能中的一个错误。
解决方法:我只让我的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(...)