OPTIONS 请求引发的分析
阅读提纲:
- 为什么会出现 OPTIONS 请求?
- 什么情况下会出现 OPTIONS 请求?
- OPTIONS 请求会发送什么内容?
跨域前端访问后端时,所有的 Ajax HTTP 请求都会先发送一个 OPTIONS 请求,接下来再发送真实请求。图略。
那么问题来了:为什么会出现 OPTIONS 请求?什么情况下会出现 OPTIONS 请求?OPTIONS 请求会发送什么内容?
-
为什么会出现 OPTIONS 请求?
当 HTTP 请求跨域时,浏览器会自动先发送一个 OPTIONS 请求(预检请求,preflight request)到相同的目标地址,目的是获知服务端是否允许浏览器发送该跨域请求,因为某些 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求)可能对服务器数据产生副作用。
什么是跨域?
当请求端和目标端的 URL 的协议或域名或端口有任意一项不一致,则该请求跨域。
比如下表中的 URL1 和 URL2 都属于跨域:
URL1
|
URL2
|
原因
|
---|---|---|
http://localhost/ | https://localhost/ | 协议不同 |
http://localhost/ | http://127.0.0.1/ | 域名不同 |
http://localhost:80/ | http://localhost:81/ | 端口不同 |
-
什么情况下会出现 OPTIONS 请求?
其实发送 OPTIONS 请求还是有一定条件的。当请求满足下述任一条件时,即应首先发送预检请求:
1、使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
2、人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (需要注意额外的限制)
DPR
Downlink
Save-Data
Viewport-Width
Width
3、Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain
4、请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
5、请求中使用了ReadableStream对象。
-
OPTIONS 请求会发送什么内容?
OPTIONS 请求发送的请求信息如下图所示:
其中最重要的是:
Access-Control-Request-Method: GET
Access-Control-Request-Headers: accesstoken, refreshtoken
其中:
“Access-Control-Request-Method”指令告诉服务器实际发送的请求方法是“GET”,“Access-Control-Request-Headers”指令告诉服务器实际发送的请求头会包含这两个字段。
如果服务器同意接收客户端这个请求,就会返回如下两个字段:
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: accesstoken, refreshtoken
如果服务器允许客户端的域访问,则会返回如下字段(假设客户端的域是 http://loclahost.cn):
Access-Control-Allow-Origin: http://localhost.cn
如果服务器允许客户端携带凭证(比如会话ID等 COOKIE 信息),则会返回如下字段:
Access-Control-Allow-Credentials: true
参考:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests