尚未完整,待细化
本文总结于: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。 |