尚未完整,待細化
本文總結於:https://developer.mozilla.org/en-US/docs/Glossary/CORS
本文參考了:https://fetch.spec.whatwg.org/#cors-request
CORS時,何時會發CORS-preflight request
下面任意一個條件被滿足時,就會發CORS-preflight request。即:
一、如果使用了下面任一個HTTP METHOD,則就發CORS-preflight request
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
二、或者,如果CORS-actual request設置了下面header以外的header,則就發CORS-preflight request
- `User-Agent`
- `Accept-Charset`
- `Accept-Encoding`
- `Access-Control-Request-Headers`
- `Access-Control-Request-Method`
- `Connection`
- `Content-Length`
- `Cookie`
- `Cookie2`
- `Date`
- `DNT`
- `Expect`
- `Host`
- `Keep-Alive`
- `Origin`
- `Referer`
- `TE`
- `Trailer`
- `Transfer-Encoding`
- `Upgrade`
- `Via`
- `Proxy-`或以它開頭的
- `Sec-`或以它開頭的
- `Accept`
- `Accept-Language`
- `Content-Language`
- Content-Type( with a MIME type of its parsed value (ignoring parameters) of either application/x-www-form-urlencoded, multipart/form-data, or text/plain. )。即:出現Content-Type時,若它的值是 application/x-www-form-urlencoded, multipart/form-data, or text/plain 之一時,不發CORS-preflight request;否則就發。
- `DPR`
- `Downlink`
- `Save-Data`
- `Viewport-Width`
- `Width`
三、或者,如果Content-Type設置了三個值以外的值時,則就發CORS-preflight request。(注:上面已經說過了,不過,爲了和原文結構保持一致,再列一次該規則)
- 出現Content-Type時,若它的值是 application/x-www-form-urlencoded, multipart/form-data, or text/plain 之一時,不發CORS-preflight request;否則就發。
四、或者,如果CORS-actual request中的XMLHttpRequestUpload對象註冊了1或多個event listeners,則就發CORS-preflight request
五、或者,如果CORS-actual request中用到了ReadableStream對象,則就發CORS-preflight request
再來看下和CORS相關的全部header
CORS相關的全部header
NO. | header | 舉例 |
---|---|---|
下面兩個header:放在 CORS-preflight request 中 | ||
1 |
Access-Control-Request-Method
放在 CORS-preflight request 中。
它告知服務器後續的CORS-actual request將使用這個HTTP METHOD。此時,CORS-preflight request的response則回饋`Access-Control-Allow-Methods`。
|
Access-Control-Request-Method: POST
意思是:它告知服務器:“後續的CORS-actual request將使用 POST”。CORS-preflight request的response則回饋`Access-Control-Allow-Methods`。
|
2 |
Access-Control-Request-Headers
放在 CORS-preflight request 中。
它告知服務器後續的CORS-actual request可能會使用這些header。CORS-preflight request的response則回饋`Access-Control-Allow-Headers`。 |
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
意思是:它告知服務器:“後續的CORS-actual request可能會使用 X-PINGOTHER, Content-Type 這兩個header”。CORS-preflight request的response則回饋`Access-Control-Allow-Headers`。 |
下面四個header:放在 CORS-preflight request的response 中。 | ||
1 |
Access-Control-Allow-Methods
放在 CORS-preflight request的response 中。
當CORS-preflight request中包含`Access-Control-Request-Method`時,CORS-preflight request的response則回饋`Access-Control-Allow-Methods`。
它表明當CORS-actual request 訪問資源時,所允許使用的HTTP METHOD。
注意:`Allow` header和CORS協議沒有任何關係
|
Access-Control-Allow-Methods: POST, GET, OPTIONS
意思是:對於給定Origin的CORS-actual request,服務端支持的HTTP METHOD是 POST, GET, OPTIONS。
|
2 |
`Access-Control-Allow-Headers`
放在 CORS-preflight request的response 中。
當CORS-preflight request中包含`Access-Control-Request-Headers`時,CORS-preflight request的response則回饋` Access-Control-Allow-Headers`。
它表明當CORS-actual request 訪問資源時,服務端除了支持simple header外,還支持CORS-preflight request的response的`Access-Control-Allow-Headers`所指定的這些header。
注意:simple header(或稱爲CORS-safelisted request header)總是可以被CORS-actual request所使用的,它們無需再列在CORS-preflight request的response的`Access-Control-Allow-Headers`的值中。simple header是指下面9個header:
|
Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests
意思是:對於給定Origin的CORS-actual request,服務端除了支持simple header,還另外支持X-Custom-Header, Upgrade-Insecure-Requests這兩個header。
|
3 |
Access-Control-Max-Age
放在 CORS-preflight request的response 中。
它表明 CORS-preflight request的response所返回的`Access-Control-Allow-Methods` 和 `Access-Control-Allow-Headers`的值將被緩存的秒數。
-1是禁止緩存。即:每一個CORS-actual request都要先發一次CORS-preflight request。 Firefox最大值是24hours,即86400秒。Firefox默認值呢?文檔沒說,先空着它,後續我來補充; Chromium最大值是10minutes,即600秒,Chromium默認值是5秒;
|
Access-Control-Max-Age: 60
意思是:`Access-Control-Allow-Methods` 和 `Access-Control-Allow-Headers`的值將被緩存1分鐘。
|
4 |
Access-Control-Expose-Headers
放在 CORS-preflight request的response 中。
它表明,除了simple response header,還有這些header也可以被暴露出來供client使用。如果想要client能夠訪問simple response header之外的header,則,必須將它們列在 CORS-actual request 的response 的`Access-Control-Expose-Headers`中。
simple response header(或稱爲CORS-safelisted response header)是安全的,當CORS處理response時,它們不會被過濾掉。simple response header是指下面6個header:
|
Access-Control-Expose-Headers: Content-Length, X-Kuma-Revision
意思是:client除了能夠訪問simple response header外,還可以訪問Content-Length, X-Kuma-Revision這兩個header。 |
下面兩個header:放在 CORS-actual request的response 中。 | ||
1 |
Access-Controll-Allow-Origin
放在 CORS-actual request 的response 中。
它表明 CORS-actual request的response 能否被 來自特定origin的請求 所共享
`Access-Controll-Allow-Origin`的語法如下: Access-Control-Allow-Origin: *
`Access-Controll-Allow-Origin`的特定如下:
|
Access-Control-Allow-Origin: * |
2 |
Access-Control-Allow-Credentials
放在 CORS-actual request 的response 中。
當request的credentials mode爲"include"時,是否將response暴露給前端JavaScript代碼 Request.credentials爲"include"時,只有當Access-Control-Allow-Credentials=true時,瀏覽器纔會將response暴露給前端JavaScript代碼 Credentials是指cookies, authorization header或TLS client certificates
當其作爲preflight request的響應的一部分時,該header表明實際請求是否可以使用credentials。注意:GET無需preflight,因此,如果請求資源時使用了credentials,如果該header沒有和資源一起返回,response就被瀏覽器忽略了,response就不會返回給web content。 Access-Control-Allow-Credentials和 XMLHttpRequest.withCredentials屬性或Request()構函的credentials選項 一起使用。對於使用了credentials的CORS請求,爲了讓瀏覽器可以把response暴露給前端JavaScript代碼,server端(使用Access-Control-Allow-Credentials)和client端(設置XHR或Fetch或Ajax的credentials mode)都得表明它們將包含credentials
|
Access-Control-Allow-Credentials: true
注意:唯一的候選值就是true,且,大小寫敏感。如果不需要credentials,請完全忽略掉個header,而不是將其設置爲false。
|
下面一個header並不是只和CORS相關。 | ||
1 |
Origin
放在 CORS-preflight request 和 CORS-actual request 中,以及普通POST的request中。
Origin: ""
Origin的特點如下:
Referer: http://foo.example/examples/preflightInvocation.html
|
Origin: "" Origin: https://developer.mozilla.org
意思是:空或者https://developer.mozilla.org。 |