2017-08-16 71 views
0

我想了解整個CORS策略的工作原理。爲了解釋我的困惑,讓我給你舉個例子:瞭解頁面響應

$.get("https://www.google.com", function(response) { alert(response) }); 

上述要求將以下錯誤返回:

XMLHttpRequest cannot load https://www.google.com/ . Redirect from ' https://www.google.com/ ' to ' https://www.google.ca/?gfe_rd=cr&ei=TlqUWeGEH5HRXqW6utgI ' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' https://fiddle.jshell.net ' is therefore not allowed access.

現在,爲了該工作,谷歌將不得不塗白列表https://fiddle.jshell.net

現在,如果我想在一個平靜的API頁面上嘗試相同的事情,那就行了。我的問題很簡單,爲什麼?

試圖分析這個問題,我試着打了一個API,並分析其響應:

https://apigee.com/console/bing?req=%7B%22resource%22%3A%22web_search%22%2C%22params%22%3A%7B%22query%22%3A%7B%22query%22%3A%22sushi%22%2C%22sources%22%3A%22web%22%7D%2C%22template%22%3A%7B%22format%22%3A%22json%22%7D%2C%22headers%22%3A%7B%7D%2C%22body%22%3A%7B%22attachmentFormat%22%3A%22mime%22%2C%22attachmentContentDisposition%22%3A%22form-data%22%7D%7D%2C%22verb%22%3A%22get%22%7D

響應:

HTTP/1.1 200 
Date: 
Wed, 16 Aug 2017 14:31:32 GMT 
Content-Length: 266 
Connection: keep-alive 
Content-Type: application/json; charset=utf-8 
Server: Apigee Router 
X-Content-Type-Options: nosniff 

我來的結論,即它必須是頭。具體來說,我相信它是這個標題:Content-Type: application/json;但我不知道,我試圖理解這一點,並希望有人在這裏可以向我解釋。

+0

我不知道「在一個寧靜的API頁面上嘗試同樣的事情」的意思,但其要點是,默認情況下,瀏覽器會阻止您的前端JavaScript代碼訪問您發送的跨源請求的響應XHR或JavaScript庫中的Fetch API或Ajax方法 - 除非發送請求的服務器指示它選擇接收此類請求。而服務器表明選擇的方式是在響應中發送Access-Control-Allow-Origin響應頭。 – sideshowbarker

+0

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS是開始閱讀CORS協議如何工作的最佳地點 – sideshowbarker

回答

1

所以我做了2次測試:從控制檯運行代碼$.get("https://www.google.com", function(response) { alert(response) });片段和https://apigee.com/console/others

請求https://www.google.com我認爲發生在第一種情況是,請求從客戶端完成,下一個請求頭髮送:

:authority:www.google.com 
:method:GET 
:path:/?_=1502896196820 
:scheme:https 
accept:*/* 
accept-encoding:gzip, deflate, br 
accept-language:en-US,en;q=0.8 
origin:https://stackoverflow.com 
referer:https://stackoverflow.com/questions/45717044/understanding-page-response 
user-agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3187.0 Safari/537.36 
x-chrome-uma-enabled:1 
x-client-data:CJG2yQEIo7bJAQiMmMoBCKudygEIs53KAQjRncoBCKiiygE= 

由於谷歌並不與'Access-Control-Allow-Origin: *'回覆 - 客戶端,並在請求我有origin:https://stackoverflow.com,Chrome瀏覽器在我的情況下拋出CORS錯誤。

在第二次測試中,使用https://apigee.com/console/others並請求https://www.google.com,apigee.com似乎覆蓋頭部和發送:

GET/HTTP/1.1 
Host: 
www.google.com 
X-Target-URI: 
https://www.google.com 
Connection: 
Keep-Alive 

此外,從開發者控制檯中,我可以看到它的服務器到服務器調用,這樣任何客戶端參與投擲CORS,因此我收到了Google頁面的回覆。

UPDATE:

關於JSON API請求,這裏是從Google CloudPlatform一些有趣的信息關於CORS

Note: CORS configuration applies only to XML API requests. For JSON API requests, Cloud Storage returns the Access-Control-Allow-Origin header with the origin of the request.

因此,如果請求從客戶端進行,客戶端不應該拋出CORS因爲它獲得Access-Control-Allow-Origin與它發送的相同源。

但是,不同的API和客戶端可能會以不同方式處理請求。因此,有時Firefox不會拋出CORS。

+0

如果我誤解了請糾正我的錯誤。你說你在第一次測試中,因爲這是一個基於客戶端的請求,它不起作用。第二次嘗試工作,因爲它是一個基於服務器的請求。考慮到這一點,我的問題只針對客戶請求。當你擊中任何API時,即使從JavaScript(客戶端啓動),你也會得到json結果。我試圖理解爲什麼這樣做,而不是嘗試獲取HTML頁面,它不會工作。 – Bojan

+0

@Bojan我用谷歌雲平臺的例子更新了我的答案,也許它會闡明基於JSON的API請求。 – Mykola

+0

實際上,我認爲我的客戶端請求可以工作的原因是「Content-Type:application/json;」頭部。因爲json類型的請求不會被CORS阻塞? – Bojan