HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。
如图:
其实,这是因为在跨域的情况下,在浏览器发起"复杂请求"时主动发起的。跨域共享标准规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
简单跨域请求
简单跨域请求是指满足以下两个条件的请求。 1、HTTP方法是以下三种方法之一:
HEAD
GET
POST
2、HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
-
Content-Type
:只限于三个值,application/x-www-form-urlencoded、multipart/form-data、text/plain
简单跨域请求的部分响应头如下:
-
Access-Control-Allow-Origin
(必含)- 不可省略,否则请求按失败处理。该项控制数据的可见范围,如果希望数据对任何人都可见,可以填写"*"。 -
Access-Control-Allow-Credentials
(可选) – 该项标志着请求当中是否包含cookies
信息,只有一个可选值:true(必为小写)。如果不包含cookies
,请略去该项,而不是填写false。这一项与XmlHttpRequest2
对象当中的withCredentials
属性应保持一致,即withCredentials
为true时该项也为true;withCredentials
为false时,省略该项不写。反之则导致请求失败。 -
Access-Control-Expose-Headers
(可选) – 该项确定XmlHttpRequest2
对象当中getResponseHeader()
方法所能获得的额外信息。通常情况下,getResponseHeader()
方法只能获得如下的信息:- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
当你需要访问额外的信息时,就需要在这一项当中填写并以逗号进行分隔。
复杂跨域请求
任何一个不满足简单跨域请求要求的请求,即被认为是复杂请求,也称作带预检的跨域请求。
一个复杂请求不止发送一个包含通信内容的请求,其中最先发送的是一种**"预检"请求**,此时作为服务端,也需要返回**"预回应"**作为响应。"预检"请求实际上是对服务端的一种权限请求,只有当"预检"请求成功返回,实际请求才开始执行。
预请求以OPTIONS
形式发送,当中同样包含域,并且还包含了两项CORS
特有的内容:
-
Access-Control-Request-Method
– 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。 -
Access-Control-Request-Headers
– 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部。
显而易见,这个"预检"请求实际上就是在为之后的实际请求发送一个权限请求,在预回应返回的内容当中,服务端应当对这两项进行回复,以让浏览器确定请求是否能够成功完成。一旦预回应如期而至,所请求的权限也都已满足,才会发出真实请求,携带真实数据。
Options 请求优化
对 options 请求进行缓存,服务器端设置Access-Control-Max-Age
字段参考文章:
CORS跨域时,为何会出现一次动作,两次请求?https://mp.weixin.qq.com/s/zHxpII3LeePfTl4EOjcgCQ
说说对 options 请求的理解 https://mp.weixin.qq.com/s/zHxpII3LeePfTl4EOjcgCQ