CORS跨域

跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器  讓運行在一個 origin (domain) 上的Web應用被准許訪問來自不同源服務器上的指定的資源。當一個資源從與該資源本身所在的服務器不同的域、協議或端口請求一個資源時,資源會發起一個跨域 HTTP 請求

 

什麼時候會出現跨域?

 

URL(A) URL(B)  說明  是否允許跨域
http://www.a.com/lab/a.js http://www.a.com/script/b.js  同一域名下不同文件夾 允許
http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允許
http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不同端口 不允許
http://www.a.com/a.js https://www.a.com/b.js 同一域名,不同協議 不允許
http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名對應ip 不允許
http://www.a.com/a.js http://script.a.com/b.js 主域相同,子域不同 不允許
http://www.a.com/a.js http://a.com/b.js 同一域名,不同二級域名(同上) 不允許(cookie這種情況下也不允許訪問)
http://www.cnblogs.com/a.js http://www.a.com/b.js 不同域名 不允許


一、CORS解決方案
--------------------- 
作者:daisy_Hawen 
來源:CSDN 
原文:https://blog.csdn.net/sinat_25127047/article/details/53535171 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

比如,站點 http://domain-a.com 的某 HTML 頁面通過 <img> 的 src 請求 http://domain-b.com/image.jpg。網絡上的許多頁面都會加載來自不同域的CSS樣式表,圖像和腳本等資源。

 

出於安全原因,瀏覽器限制從腳本內發起的跨源HTTP請求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 這意味着使用這些API的Web應用程序只能從加載應用程序的同一個域請求HTTP資源,除非響應報文包含了正確CORS響應頭。

  (譯者注:這段描述不準確,並不一定是瀏覽器限制了發起跨站請求,也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。)

跨域資源共享( CORS )機制允許 Web 應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。現代瀏覽器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 請求所帶來的風險。

誰應該讀這篇文章?

說實話,每個人。

更具體地來講,這篇文章適用於網站管理員、後端和前端開發者。現代瀏覽器處理跨域資源共享的客戶端部分,包括HTTP頭和相關策略的執行。但是這一新標準意味着服務器需要處理新的請求頭和響應頭。對於服務端的支持,開發者可以閱讀補充材料 cross-origin sharing from a server perspective (with PHP code snippets) 。

什麼情況下需要 CORS ?

跨域資源共享標準( cross-origin sharing standard )允許在下列場景中使用跨域 HTTP 請求:

本文概述了跨域資源共享機制及其所涉及的 HTTP 頭。

功能概述

跨域資源共享標準新增了一組 HTTP 首部字段,允許服務器聲明哪些源站通過瀏覽器有權限訪問哪些資源。另外,規範要求,對那些可能對服務器數據產生副作用的 HTTP 請求方法(特別是 GET 以外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求(preflight request),從而獲知服務端是否允許該跨域請求。服務器確認允許之後,才發起實際的 HTTP 請求。在預檢請求的返回中,服務器端也可以通知客戶端,是否需要攜帶身份憑證(包括 Cookies 和 HTTP 認證相關數據)。

CORS請求失敗會產生錯誤,但是爲了安全,在JavaScript代碼層面是無法獲知到底具體是哪裏出了問題。你只能查看瀏覽器的控制檯以得知具體是哪裏出現了錯誤。

接下來的內容將討論相關場景,並剖析該機制所涉及的 HTTP 首部字段。

若干訪問控制場景

這裏,我們使用三個場景來解釋跨域資源共享機制的工作原理。這些例子都使用 XMLHttpRequest 對象。

本文中的 JavaScript 代碼片段都可以從 http://arunranga.com/examples/access-control/ 獲得。另外,使用支持跨域  XMLHttpRequest 的瀏覽器訪問該地址,可以看到代碼的實際運行結果。

關於服務端對跨域資源共享的支持的討論,請參見這篇文章: Server-Side_Access_Control (CORS)

 

某些請求不會觸發 CORS 預檢請求。本文稱這樣的請求爲“簡單請求”,請注意,該術語並不屬於 Fetch (其中定義了 CORS)規範。若請求滿足所有下述條件,則該請求可視爲“簡單請求”:

注意: 這些跨域請求與瀏覽器發出的其他跨域請求並無二致。如果服務器未返回正確的響應首部,則請求方不會收到任何數據。因此,那些不允許跨域請求的網站無需爲這一新的 HTTP 訪問控制特性擔心。

注意: WebKit Nightly 和 Safari Technology Preview 爲AcceptAccept-Language, 和 Content-Language 首部字段的值添加了額外的限制。如果這些首部字段的值是“非標準”的,WebKit/Safari 就不會將這些請求視爲“簡單請求”。WebKit/Safari 並沒有在文檔中列出哪些值是“非標準”的,不過我們可以在這裏找到相關討論:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它瀏覽器並不支持這些額外的限制,因爲它們不屬於規範的一部分。

比如說,假如站點 http://foo.example 的網頁應用想要訪問 http://bar.other 的資源。http://foo.example 的網頁中可能包含類似於下面的 JavaScript 代碼:

<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> invocation <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">XMLHttpRequest</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">var</span> url <span style="color:#9a6e3a">=</span> <span style="color:#669900">'http://bar.other/resources/public-data/'</span><span style="color:#999999">;</span>
   
<span style="color:#0077aa">function</span> <span style="color:#dd4a68">callOtherDomain</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
  <span style="color:#0077aa">if</span><span style="color:#999999">(</span>invocation<span style="color:#999999">)</span> <span style="color:#999999">{</span>    
    invocation<span style="color:#999999">.</span><span style="color:#dd4a68">open</span><span style="color:#999999">(</span><span style="color:#669900">'GET'</span><span style="color:#999999">,</span> url<span style="color:#999999">,</span> <span style="color:#990055">true</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
    invocation<span style="color:#999999">.</span>onreadystatechange <span style="color:#9a6e3a">=</span> handler<span style="color:#999999">;</span>
    invocation<span style="color:#999999">.</span><span style="color:#dd4a68">send</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> 
  <span style="color:#999999">}</span>
<span style="color:#999999">}</span></code></span>

客戶端和服務器之間使用 CORS 首部字段來處理跨域權限:

分別檢視請求報文和響應報文:

<span style="color:#333333"><code class="language-shell">GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 <span style="color:#999999">(</span>Macintosh<span style="color:#999999">;</span> U<span style="color:#999999">;</span> Intel Mac OS X 10.5<span style="color:#999999">;</span> en-US<span style="color:#999999">;</span> rv:1.9.1b3pre<span style="color:#999999">)</span> Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml<span style="color:#999999">;</span>q<span style="color:#9a6e3a">=</span>0.9,*/*<span style="color:#999999">;</span>q<span style="color:#9a6e3a">=</span>0.8
Accept-Language: en-us,en<span style="color:#999999">;</span>q<span style="color:#9a6e3a">=</span>0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8<span style="color:#999999">;</span>q<span style="color:#9a6e3a">=</span>0.7,*<span style="color:#999999">;</span>q<span style="color:#9a6e3a">=</span>0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout<span style="color:#9a6e3a">=</span>2, max<span style="color:#9a6e3a">=</span>100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

<span style="color:#999999">[</span>XML Data<span style="color:#999999">]</span></code></span>

第 1~10 行是請求首部。第10行 的請求首部字段 Origin 表明該請求來源於 http://foo.exmaple

第 13~22 行是來自於 http://bar.other 的服務端響應。響應中攜帶了響應首部字段 Access-Control-Allow-Origin(第 16 行)。使用 Origin 和 Access-Control-Allow-Origin 就能完成最簡單的訪問控制。本例中,服務端返回的 Access-Control-Allow-Origin: * 表明,該資源可以被任意外域訪問。如果服務端僅允許來自 http://foo.example 的訪問,該首部字段的內容如下:

Access-Control-Allow-Origin: http://foo.example

現在,除了 http://foo.example,其它外域均不能訪問該資源(該策略由請求首部中的 ORIGIN 字段定義,見第10行)。Access-Control-Allow-Origin 應當爲 * 或者包含由 Origin 首部字段所指明的域名。

預檢請求

與前述簡單請求不同,“需預檢的請求”要求必須首先使用 OPTIONS   方法發起一個預檢請求到服務器,以獲知服務器是否允許該實際請求。"預檢請求“的使用,可以避免跨域請求對服務器的用戶數據產生未預期的影響。

當請求滿足下述任一條件時,即應首先發送預檢請求:

注意: WebKit Nightly 和 Safari Technology Preview 爲AcceptAccept-Language, 和 Content-Language 首部字段的值添加了額外的限制。如果這些首部字段的值是“非標準”的,WebKit/Safari 就不會將這些請求視爲“簡單請求”。WebKit/Safari 並沒有在文檔中列出哪些值是“非標準”的,不過我們可以在這裏找到相關討論:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-LanguageAllow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它瀏覽器並不支持這些額外的限制,因爲它們不屬於規範的一部分。

如下是一個需要執行預檢請求的 HTTP 請求:

<span style="color:#333333"><code class="language-js"><span style="color:#0077aa">var</span> invocation <span style="color:#9a6e3a">=</span> <span style="color:#0077aa">new</span> <span style="color:#dd4a68">XMLHttpRequest</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#0077aa">var</span> url <span style="color:#9a6e3a">=</span> <span style="color:#669900">'http://bar.other/resources/post-here/'</span><span style="color:#999999">;</span>
<span style="color:#0077aa">var</span> body <span style="color:#9a6e3a">=</span> <span style="color:#669900">'<?xml version="1.0"?><person><name>Arun</name></person>'</span><span style="color:#999999">;</span>
    
<span style="color:#0077aa">function</span> <span style="color:#dd4a68">callOtherDomain</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>
  <span style="color:#0077aa">if</span><span style="color:#999999">(</span>invocation<span style="color:#999999">)</span>
    <span style="color:#999999">{</span>
      invocation<span style="color:#999999">.</span><span style="color:#dd4a68">open</span><span style="color:#999999">(</span><span style="color:#669900">'POST'</span><span style="color:#999999">,</span> url<span style="color:#999999">,</span> <span style="color:#990055">true</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
      invocation<span style="color:#999999">.</span><span style="color:#dd4a68">setRequestHeader</span><span style="color:#999999">(</span><span style="color:#669900">'X-PINGOTHER'</span><span style="color:#999999">,</span> <span style="color:#669900">'pingpong'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
      invocation<span style="color:#999999">.</span><span style="color:#dd4a68">setRequestHeader</span><span style="color:#999999">(</span><span style="color:#669900">'Content-Type'</span><span style="color:#999999">,</span> <span style="color:#669900">'application/xml'</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
      invocation<span style="color:#999999">.</span>onreadystatechange <span style="color:#9a6e3a">=</span> handler<span style="color:#999999">;</span>
      invocation<span style="color:#999999">.</span><span style="color:#dd4a68">send</span><span style="color:#999999">(</span>body<span style="color:#999999">)</span><span style="color:#999999">;</span> 
    <span style="color:#999999">}</span>
<span style="color:#999999">}</span>

<span style="color:#9a6e3a">...</span><span style="color:#9a6e3a">...</span></code></span>

上面的代碼使用 POST 請求發送一個 XML 文檔,該請求包含了一個自定義的請求首部字段(X-PINGOTHER: pingpong)。另外,該請求的 Content-Type 爲 application/xml。因此,該請求需要首先發起“預檢請求”。

 1.OPTIONS /resources/post-here/ HTTP/1.1
 2.Host: bar.other
 3.User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
 4.Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 5.Accept-Language: en-us,en;q=0.5
 6.Accept-Encoding: gzip,deflate
 7.Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
 8.Connection: keep-alive
 9.Origin: http://foo.example
10.Access-Control-Request-Method: POST
11.Access-Control-Request-Headers: X-PINGOTHER, Content-Type
12.
13.
14.HTTP/1.1 200 OK
15.Date: Mon, 01 Dec 2008 01:15:39 GMT
16.Server: Apache/2.0.61 (Unix)
17.Access-Control-Allow-Origin: http://foo.example
18.Access-Control-Allow-Methods: POST, GET, OPTIONS
19.Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
20.Access-Control-Max-Age: 86400
21.Vary: Accept-Encoding, Origin
22.Content-Encoding: gzip
23.Content-Length: 0
24.Keep-Alive: timeout=2, max=100
25.Connection: Keep-Alive
26.Content-Type: text/plain

預檢請求完成之後,發送實際請求:

POST /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: http://foo.example
Pragma: no-cache
Cache-Control: no-cache

<?xml version="1.0"?><person><name>Arun</name></person>


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some GZIP'd payload]

瀏覽器檢測到,從 JavaScript 中發起的請求需要被預檢。從上面的報文中,我們看到,第 1~12 行發送了一個使用 OPTIONS 方法的“預檢請求”。 OPTIONS 是 HTTP/1.1 協議中定義的方法,用以從服務器獲取更多信息。該方法不會對服務器資源產生影響。 預檢請求中同時攜帶了下面兩個首部字段:

Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

首部字段 Access-Control-Request-Method 告知服務器,實際請求將使用 POST 方法。首部字段 Access-Control-Request-Headers 告知服務器,實際請求將攜帶兩個自定義請求首部字段:X-PINGOTHER 與 Content-Type。服務器據此決定,該實際請求是否被允許。

第14~26 行爲預檢請求的響應,表明服務器將接受後續的實際請求。重點看第 17~20 行:

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

首部字段 Access-Control-Allow-Methods 表明服務器允許客戶端使用 POST, GET 和 OPTIONS 方法發起請求。該字段與 HTTP/1.1 Allow: response header 類似,但僅限於在需要訪問控制的場景中使用。

首部字段 Access-Control-Allow-Headers 表明服務器允許請求中攜帶字段 X-PINGOTHER Content-Type。與 Access-Control-Allow-Methods 一樣,Access-Control-Allow-Headers 的值爲逗號分割的列表。

最後,首部字段 Access-Control-Max-Age 表明該響應的有效時間爲 86400 秒,也就是 24 小時。在有效時間內,瀏覽器無須爲同一請求再次發起預檢請求。請注意,瀏覽器自身維護了一個最大有效時間,如果該首部字段的值超過了最大有效時間,將不會生效。

預檢請求與重定向

大多數瀏覽器不支持針對於預檢請求的重定向。如果一個預檢請求發生了重定向,瀏覽器將報告錯誤:

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

Request requires preflight, which is disallowed to follow cross-origin redirect

CORS 最初要求該行爲,不過在後續的修訂中廢棄了這一要求

在瀏覽器的實現跟上規範之前,有兩種方式規避上述報錯行爲:

  • 在服務端去掉對預檢請求的重定向;
  • 將實際請求變成一個簡單請求。

如果上面兩種方式難以做到,我們仍有其他辦法:

不過,如果請求是由於存在 Authorization 字段而引發了預檢請求,則這一方法將無法使用。這種情況只能由服務端進行更改。

附帶身份憑證的請求

Fetch 與 CORS 的一個有趣的特性是,可以基於  HTTP cookies 和 HTTP 認證信息發送身份憑證。一般而言,對於跨域 XMLHttpRequest 或 Fetch 請求,瀏覽器不會發送身份憑證信息。如果要發送憑證信息,需要設置 XMLHttpRequest 的某個特殊標誌位。

本例中,http://foo.example 的某腳本向 http://bar.other 發起一個GET 請求,並設置 Cookies:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
    
function callOtherDomain(){
  if(invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

第 7 行將 XMLHttpRequest 的 withCredentials 標誌設置爲 true,從而向服務器發送 Cookies。因爲這是一個簡單 GET 請求,所以瀏覽器不會對其發起“預檢請求”。但是,如果服務器端的響應中未攜帶 Access-Control-Allow-Credentials: true ,瀏覽器將不會把響應內容返回給請求的發送者。

客戶端與服務器端交互示例如下:

GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.6
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain


[text/plain payload]

即使第 11 行指定了 Cookie 的相關信息,但是,如果 bar.other 的響應中缺失 Access-Control-Allow-Credentials: true(第 19 行),則響應內容不會返回給請求的發起者。

附帶身份憑證的請求與通配符

對於附帶身份憑證的請求,服務器不得設置 Access-Control-Allow-Origin 的值爲“*”。

這是因爲請求的首部中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值爲“*”,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置爲 http://foo.example,則請求將成功執行。

另外,響應首部中也攜帶了 Set-Cookie 字段,嘗試對 Cookie 進行修改。如果操作失敗,將會拋出異常。

HTTP 響應首部字段

本節列出了規範所定義的響應首部字段。上一小節中,我們已經看到了這些首部字段在實際場景中是如何工作的。

Access-Control-Allow-Origin

響應首部中可以攜帶一個 Access-Control-Allow-Origin 字段,其語法如下:

<span style="color:#333333"><code class="language-html">Access-Control-Allow-Origin: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>origin</span><span style="color:#999999">></span></span> | *</code></span>

其中,origin 參數的值指定了允許訪問該資源的外域 URI。對於不需要攜帶身份憑證的請求,服務器可以指定該字段的值爲通配符,表示允許來自所有域的請求。

例如,下面的字段值將允許來自 http://mozilla.com 的請求:

<span style="color:#333333"><code class="language-html">Access-Control-Allow-Origin: http://mozilla.com</code></span>

如果服務端指定了具體的域名而非“*”,那麼響應首部中的 Vary 字段的值必須包含 Origin。這將告訴客戶端:服務器對不同的源站返回不同的內容。

Access-Control-Expose-Headers

譯者注:在跨域訪問時,XMLHttpRequest對象的getResponseHeader()方法只能拿到一些最基本的響應頭,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要訪問其他頭,則需要服務器設置本響應頭。

Access-Control-Expose-Headers 頭讓服務器把允許瀏覽器訪問的頭放入白名單,例如:

<span style="color:#333333"><code class="language-html">Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header</code></span>

這樣瀏覽器就能夠通過getResponseHeader訪問X-My-Custom-Header和 X-Another-Custom-Header 響應頭了

Access-Control-Max-Age

Access-Control-Max-Age 頭指定了preflight請求的結果能夠被緩存多久,請參考本文在前面提到的preflight例子。

<span style="color:#333333"><code class="language-html">Access-Control-Max-Age: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>delta-seconds</span><span style="color:#999999">></span></span></code></span>

delta-seconds 參數表示preflight請求的結果在多少秒內有效。

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials 頭指定了當瀏覽器的credentials設置爲true時是否允許瀏覽器讀取response的內容。當用在對preflight預檢測請求的響應中時,它指定了實際的請求是否可以使用credentials。請注意:簡單 GET 請求不會被預檢;如果對此類請求的響應中不包含該字段,這個響應將被忽略掉,並且瀏覽器也不會將相應內容返回給網頁。

<span style="color:#333333"><code class="language-html">Access-Control-Allow-Credentials: true</code></span>

上文已經討論了附帶身份憑證的請求

Access-Control-Allow-Methods

Access-Control-Allow-Methods 首部字段用於預檢請求的響應。其指明瞭實際請求所允許使用的 HTTP 方法。

<span style="color:#333333"><code class="language-html">Access-Control-Allow-Methods: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>method</span><span style="color:#999999">></span></span>[, <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>method</span><span style="color:#999999">></span></span>]*</code></span>

相關示例見這裏

Access-Control-Allow-Headers

Access-Control-Allow-Headers 首部字段用於預檢請求的響應。其指明瞭實際請求中允許攜帶的首部字段。

<span style="color:#333333"><code class="language-html">Access-Control-Allow-Headers: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>field-name</span><span style="color:#999999">></span></span>[, <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>field-name</span><span style="color:#999999">></span></span>]*</code></span>

HTTP 請求首部字段

本節列出了可用於發起跨域請求的首部字段。請注意,這些首部字段無須手動設置。 當開發者使用 XMLHttpRequest 對象發起跨域請求時,它們已經被設置就緒。

Origin

Origin 首部字段表明預檢請求或實際請求的源站。

<span style="color:#333333"><code class="language-html">Origin: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>origin</span><span style="color:#999999">></span></span></code></span>

origin 參數的值爲源站 URI。它不包含任何路徑信息,只是服務器名稱。

Note: 有時候將該字段的值設置爲空字符串是有用的,例如,當源站是一個 data URL 時。

注意,不管是否爲跨域請求,ORIGIN 字段總是被髮送。

Access-Control-Request-Method

Access-Control-Request-Method 首部字段用於預檢請求。其作用是,將實際請求所使用的 HTTP 方法告訴服務器。

<span style="color:#333333"><code class="language-html">Access-Control-Request-Method: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>method</span><span style="color:#999999">></span></span></code></span>

相關示例見這裏

Access-Control-Request-Headers

Access-Control-Request-Headers 首部字段用於預檢請求。其作用是,將實際請求所攜帶的首部字段告訴服務器。

<span style="color:#333333"><code class="language-html">Access-Control-Request-Headers: <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>field-name</span><span style="color:#999999">></span></span>[, <span style="color:#990055"><span style="color:#990055"><span style="color:#999999"><</span>field-name</span><span style="color:#999999">></span></span>]*</code></span>

相關示例見這裏

規範

Specification Status Comment
Fetch
CORS
Living Standard New definition; supplants CORS specification.
Unknown Unknown Initial definition.

瀏覽器兼容性

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 4 3.5 8 (via XDomainRequest)
10
12 4

注:

  • IE 10 提供了對規範的完整支持,但在較早版本(8 和 9)中,CORS 機制是藉由 XDomainRequest 對象完成的。
  • Firefox 3.5 引入了對 XMLHttpRequests 和 Web 字體的跨域支持(但最初的實現並不完整,這在後續版本中得到完善);Firefox 7 引入了對 WebGL 貼圖的跨域支持;Firefox 9 引入了對 drawImage 的跨域支持。

 

本文轉載自:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#%E8%A7%84%E8%8C%83

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章