CORS-safelisted request header 预检请求 OPTIONS
1、
Content-Type 只在其值属于 MIME 类型
application/x-www-form-urlencoded
, multipart/form-data
或 text/plain
中的一种时 ,为跨域安全请求头。
实践:
Access-Control-Allow-Headers
响应首部 Access-Control-Allow-Headers
用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Request-Headers
字段中出现的首部信息。
简单首部,如 simple headers、Accept
、Accept-Language
、Content-Language
、Content-Type
(只限于解析后的值为 application/x-www-form-urlencoded、
multipart/form-data
或 text/plain 三种MIME类型(不包括参数)),它们始终是被支持的,不需要在这个首部特意列出。
如果请求中含有 Access-Control-Request-Headers
字段,那么这个首部是必要的。
Header type | Response header |
---|---|
Forbidden header name | no |
语法
Access-Control-Allow-Headers: <header-name>[, <header-name>]* Access-Control-Allow-Headers: *
指令
<header-name>
- 可支持的请求首部名字。请求头会列出所有支持的首部列表,用逗号隔开。
注意以下这些特定的首部是一直允许的:Accept
, Accept-Language
, Content-Language
, Content-Type
(但只在其值属于 MIME 类型 application/x-www-form-urlencoded
, multipart/form-data
或 text/plain
中的一种时)。这些被称作simple headers,你无需特意声明它们。
*
(wildcard)
对于没有凭据的请求(没有HTTP cookie或HTTP认证信息的请求),值“ *
”仅作为特殊的通配符值。 在具有凭据的请求中,它被视为没有特殊语义的文字标头名称“ *”。 请注意,Authorization
标头不能使用通配符,并且始终需要明确列出。
示例
自定义的请求头
下面是 Access-Control-Allow-Headers
标头的一个示例。 它表明,除了CORS安全清单列出的请求标头外,对服务器的CORS请求还支持名为X-Custom-Header的自定义标头。
Access-Control-Allow-Headers: X-Custom-Header
Multiple headers
此示例展示了支持多个标头时的 Access-Control-Allow-Headers
。
Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests
Example preflight request
让我们看一个涉及Access-Control-Allow-Headers
的预检请求示例。
Request
First, the request. The preflight request is an OPTIONS
request which includes some combination of the three preflight request headers: Access-Control-Request-Method
, Access-Control-Request-Headers
, and Origin
, such as:
OPTIONS /resource/foo
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org
Response
If the server allows CORS requests to use the DELETE
method, it responds with an Access-Control-Allow-Methods
response header, which lists DELETE
along with the other methods it supports:
HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
If the requested method isn't supported, the server will respond with an error.
Access-Control-Allow-Headers - HTTP | MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
- For
Content-Type
: needs to have a MIME type of its parsed value (ignoring parameters) of eitherapplication/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
.
CORS-safelisted request header
CORS-safelisted request header
A CORS-safelisted request header is one of the following HTTP headers:
When containing only these headers (and values that meet the additional requirements laid out below), a requests doesn't need to send a preflight request in the context of CORS.
You can safelist more headers using the Access-Control-Allow-Headers
header and also list the above headers there to circumvent the following additional restrictions:
Additional restrictions
CORS-safelisted headers must also fulfill the following requirements in order to be a CORS-safelisted request header:
- For
Accept-Language
andContent-Language
: can only have values consisting of0-9
,A-Z
,a-z
, space or*,-.;=
. - For
Accept
andContent-Type
: can't contain a CORS-unsafe request header byte:0x00-0x1F
(except for0x09 (HT)
, which is allowed),"():<>?@[\]{}
, and0x7F (DEL)
. - For
Content-Type
: needs to have a MIME type of its parsed value (ignoring parameters) of eitherapplication/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
. - For any header: the value’s length can't be greater than 128.
See also
Request header(请求头)
请求头是 HTTP 头的一种,它可在 HTTP 请求中使用,并且和请求主体无关 。某些请求头如 Accept
、Accept-*
、 If-*
允许执行条件请求。某些请求头如:Cookie
, User-Agent
和 Referer
描述了请求本身以确保服务端能返回正确的响应。
并非所有出现在请求中的 HTTP 首部都属于请求头,例如在 POST
请求中经常出现的 Content-Length
实际上是一个代表请求主体大小的 entity header,虽然你也可以把它叫做请求头。
此外,CORS 定义了一个叫做 simple headers 的集合,它是请求头集合的一个子集。如果某次请求是只包含 simple header 的话,则被认为是简单请求,不会触发请求预检(preflight)。
Request header
A request header is an HTTP header that can be used in an HTTP request to provide information about the request context, so that the server can tailor the response. For example, the Accept-*
headers indicate the allowed and preferred formats of the response. Other headers can be used to supply authentication credentials (e.g. Authorization
), to control caching, or to get information about the user agent or referrer, etc.
Not all headers that can appear in a request are referred to as request headers by the specification. For example, the Content-Type
header is referred to as a representation header.
In addition, CORS defines a subset of request headers as simple headers, request headers that are always considered authorized and are not explicitly listed in responses to preflight requests.
Preflight request - 术语表 | MDN https://developer.mozilla.org/zh-CN/docs/Glossary/Preflight_request
Preflight request
一个 CORS 预检请求是用于检查服务器是否支持 CORS 即跨域资源共享。
它一般是用了以下几个 HTTP 请求首部的 OPTIONS
请求:Access-Control-Request-Method
和 Access-Control-Request-Headers
,以及一个 Origin
首部。
当有必要的时候,浏览器会自动发出一个预检请求;所以在正常情况下,前端开发者不需要自己去发这样的请求。
举个例子,一个客户端可能会在实际发送一个 DELETE
请求之前,先向服务器发起一个预检请求,用于询问是否可以向服务器发起一个 DELETE
请求:
OPTIONS /resource/foo Access-Control-Request-Method: DELETE Access-Control-Request-Headers: origin, x-requested-with Origin: https://foo.bar.org
如果服务器允许,那么服务器就会响应这个预检请求。并且其响应首部 Access-Control-Allow-Methods
会将 DELETE
包含在其中:
HTTP/1.1 200 OK Content-Length: 0 Connection: keep-alive Access-Control-Allow-Origin: https://foo.bar.org Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE Access-Control-Max-Age: 86400
Preflight request
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers.
It is an OPTIONS
request, using three HTTP request headers: Access-Control-Request-Method
, Access-Control-Request-Headers
, and the Origin
header.
A preflight request is automatically issued by a browser and in normal cases, front-end developers don't need to craft such requests themselves. It appears when request is qualified as "to be preflighted" and omitted for simple requests.
For example, a client might be asking a server if it would allow a DELETE
request, before sending a DELETE
request, by using a preflight request:
OPTIONS /resource/foo Access-Control-Request-Method: DELETE Access-Control-Request-Headers: origin, x-requested-with Origin: https://foo.bar.org
If the server allows it, then it will respond to the preflight request with an Access-Control-Allow-Methods
response header, which lists DELETE
:
HTTP/1.1 204 No Content Connection: keep-alive Access-Control-Allow-Origin: https://foo.bar.org Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE Access-Control-Max-Age: 86400
The preflight response can be optionally cached for the requests created in the same URL using Access-Control-Max-Age
header like in the above example.
OPTIONS
HTTP 的 OPTIONS 方法
用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。
Request has body | No |
---|---|
Successful response has body | Yes |
Safe | Yes |
Idempotent | Yes |
Cacheable (en-US) | No |
Allowed in HTML forms | No |
语法
OPTIONS /index.html HTTP/1.1 OPTIONS * HTTP/1.1
示例
检测服务器所支持的请求方法
可以使用 OPTIONS 方法对服务器发起请求,以检测服务器支持哪些 HTTP 方法:
curl -X OPTIONS http://example.org -i
响应报文包含一个 Allow
首部字段,该字段的值表明了服务器支持的所有 HTTP 方法:
HTTP/1.1 200 OK Allow: OPTIONS, GET, HEAD, POST Cache-Control: max-age=604800 Date: Thu, 13 Oct 2016 11:45:00 GMT Expires: Thu, 20 Oct 2016 11:45:00 GMT Server: EOS (lax004/2813) x-ec-custom-error: 1 Content-Length: 0
CORS 中的预检请求
在 CORS 中,可以使用 OPTIONS 方法发起一个预检请求,以检测实际请求是否可以被服务器所接受。预检请求报文中的 Access-Control-Request-Method
首部字段告知服务器实际请求所使用的 HTTP 方法;Access-Control-Request-Headers
首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
OPTIONS /resources/post-here/ HTTP/1.1 Host: bar.other 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 Origin: http://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type
服务器所返回的 Access-Control-Allow-Methods
首部字段将所有允许的请求方法告知客户端。该首部字段与 Allow
类似,但只能用于涉及到 CORS 的场景中。
HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) 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 Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
规范
Specification | Title |
---|---|
RFC 7231, section 4.3.7: OPTIONS | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |
OPTIONS
The HTTP OPTIONS
method requests permitted communication options for a given URL or server. A client can specify a URL with this method, or an asterisk (*
) to refer to the entire server.
Request has body | No |
---|---|
Successful response has body | Yes |
Safe | Yes |
Idempotent | Yes |
Cacheable | No |
Allowed in HTML forms | No |
Syntax
OPTIONS /index.html HTTP/1.1 OPTIONS * HTTP/1.1
Examples
Identifying allowed request methods
To find out which request methods a server supports, one can use the curl
command-line program to issue an OPTIONS
request:
curl -X OPTIONS https://example.org -i
The response then contains an Allow
header that holds the allowed methods:
HTTP/1.1 204 No Content Allow: OPTIONS, GET, HEAD, POST Cache-Control: max-age=604800 Date: Thu, 13 Oct 2016 11:45:00 GMT Server: EOS (lax004/2813)
Preflighted requests in CORS
In CORS, a preflight request is sent with the OPTIONS
method so that the server can respond if it is acceptable to send the request. In this example, we will request permission for these parameters:
- The
Access-Control-Request-Method
header sent in the preflight request tells the server that when the actual request is sent, it will have aPOST
request method. - The
Access-Control-Request-Headers
header tells the server that when the actual request is sent, it will have theX-PINGOTHER
andContent-Type
headers.
OPTIONS /resources/post-here/ HTTP/1.1 Host: bar.example 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 Connection: keep-alive Origin: https://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type
The server now can respond if it will accept a request under these circumstances. In this example, the server response says that:
Access-Control-Allow-Origin
-
The
https://foo.example
origin is permitted to request thebar.example/resources/post-here/
URL via the following: Access-Control-Allow-Methods
-
POST
,GET
, andOPTIONS
are permitted methods for the URL. (This header is similar to theAllow
response header, but used only for CORS.) Access-Control-Allow-Headers
-
Any script inspecting the response is permitted to read the values of the
X-PINGOTHER
andContent-Type
headers. Access-Control-Max-Age
-
The above permissions may be cached for 86,400 seconds (1 day).
HTTP/1.1 204 No Content Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400 Vary: Accept-Encoding, Origin Keep-Alive: timeout=2, max=100 Connection: Keep-Alive
Specifications
Specification |
---|
Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content (HTTP/1.1 Semantics and Content) # OPTIONS |