您已針對跨源資源共享(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(...)