Cross-Origin Resource Sharing (CORS)

尚未完整,待細化

本文總結於: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

  1. PUT
  2. DELETE
  3. CONNECT
  4. OPTIONS
  5. TRACE
  6. PATCH

二、或者,如果CORS-actual request設置了下面header以外的header,則就發CORS-preflight request

  1. `User-Agent`
  2. `Accept-Charset`
  3. `Accept-Encoding`
  4. `Access-Control-Request-Headers`
  5. `Access-Control-Request-Method`
  6. `Connection`
  7. `Content-Length`
  8. `Cookie`
  9. `Cookie2`
  10. `Date`
  11. `DNT`
  12. `Expect`
  13. `Host`
  14. `Keep-Alive`
  15. `Origin`
  16. `Referer`
  17. `TE`
  18. `Trailer`
  19. `Transfer-Encoding`
  20. `Upgrade`
  21. `Via`
  22. `Proxy-`或以它開頭的
  23. `Sec-`或以它開頭的
  24. `Accept`
  25. `Accept-Language`
  26. `Content-Language`
  27. 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;否則就發。
  28. `DPR`
  29. `Downlink`
  30. `Save-Data`
  31. `Viewport-Width`
  32. `Width`

三、或者,如果Content-Type設置了三個值以外的值時,則就發CORS-preflight request。(注:上面已經說過了,不過,爲了和原文結構保持一致,再列一次該規則)

  1. 出現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

CORS headers
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:

  1. Accept,
  2. Accept-Language,
  3. Content-Language,
  4. 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 之一時,Content-Type纔算是simple header。
  5. DPR
  6. Downlink
  7. Save-Data
  8. Viewport-Width
  9. Width

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:

  1. Cache-Control
  2. Content-Language
  3. Content-Type
  4. Expires
  5. Last-Modified
  6. Pragma

 

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-Control-Allow-Origin: <origin>
Access-Control-Allow-Origin: null

 

`Access-Controll-Allow-Origin`的特定如下:

  1. 當請求中不包含credentials時,*表明允許任何origin訪問所請求的資源;
  2. 當請求中包含credentials時,指定*則會報錯;
  3. 只能指定一個origin;

 

Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: https://developer.mozilla.org
Access-Control-Allow-Origin: null

     
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`是request header,它表明fetch是從哪裏來的。Origin語法如下:

Origin: ""
Origin: <scheme> "://" <hostname> [ ":" <port> ]

 

Origin的特點如下:

  1. 非CORS的普通POST請求中也會包含它。
  2. 它和`Referer`類似,但,`Origin`只包含服務器名字;`Referer`則包含完整的路徑信息。
  3. 它的值可以爲空。這也是有用處的,例如:當source是data URL時。

Referer: http://foo.example/examples/preflightInvocation.html
Origin: http://foo.example

 

Origin: ""

Origin: https://developer.mozilla.org

 

意思是:空或者https://developer.mozilla.org。

 

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