什么是 OPTIONS 请求?为什么会有 OPTIONS 请求?
首先还是看一下官方或者比较官方的定义:
HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。 --MDN WEB DOCS
同时 OPTIONS 请求具备以下特性:
选项 | 是否允许 | 备注 |
---|---|---|
Request has body | No | 没有请求体 |
Successful response has body | No | 成功的响应有响应体 |
Safe | Yes | 安全 |
Idempotent | Yes | 密等性,不变性,同一个接口请求多少次都一样 |
Cacheable | No | 不能缓存 |
Allowed in HTML forms | No | 不能在表单里使用 |
简言之,OPTIONS 请求是用于请求服务器对于某些接口等资源的支持情况的,包括各种请求方法、头部的支持情况,仅作查询使用。来个栗子,
->>> curl -X OPTIONS https://xxxx.com/micro/share/getShareRecord -i
HTTP/1.1 200 OK
Server: nginx/1.13.3
Date: Mon, 30 Jul 2018 12:50:08 GMT
Content-Length: 0
Connection: keep-alive
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
X-Frame-Options: SAMEORIGIN
Access-Control-Allow-Origin: 0
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With
通过curl来发送一个http请求,在响应头中可以发现服务器上这个接口对请求方法以及一些header的使用允许情况,也就是上面说的获取服务器对于某些资源的选项、支持情况。
OPTIONS请求方法的主要用途有两个:
1、获取服务器支持的HTTP请求方法;
2、用来检查服务器的性能。 Preflighted Requests
是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
这是浏览器给我们加上的,后端并没有做任何操作。
总结
规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
当请求满足下述任一条件时,即应首先发送预检请求(使用OPTIONS):
1、使用了下面任一 HTTP 方法:
-
PUT
-
DELETE
-
CONNECT
-
OPTIONS
-
TRACE
-
PATCH
2、跨域请求,非跨域请求不会出现options请求(CORS 跨域资源共享),人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type (but note the additional requirements below)
-
DPR
-
Downlink
-
Save-Data
-
Viewport-Width
-
Width
3、Content-Type 的值不属于下列之一:
-
application/x-www-form-urlencoded
-
multipart/form-data
-
text/plain