Ajax中跨域请求为什么触发Options请求?
Posted 前端大联盟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax中跨域请求为什么触发Options请求?相关的知识,希望对你有一定的参考价值。
茫茫人海中与你相遇
相信未来的你不会很差
来源:https://www.jianshu.com/p/578e23c2898c
简单请求浏览器请求不会触发预检请求,而非简单请求会触发预检请求
Ajax请求是由XMLHttpRequest
对象实现的(部分低版本ID浏览器不是), 而XMLHttpRequest
会遵守同源策略.也即脚本只能访问相同协议/相同主机名/相同端口的资源, 如果要突破这个限制, 那就是所谓的跨域, 此时需要遵守CORS(Cross-Origin Resource Sharing)机制.
简单粗暴实现跨域: 后台Access-Control-Allow-Origin: *
但是:还一种叫请求叫Preflighted Request(
带预检的跨域请求:由options
发出)
发送一个方法为OPTIONS的预请求(Preflighted Request), 用于试探服务端是否能接受真正的请求.
如果options获得的回应是拒绝性质的,比如404403500等http状态,就会停止post、get等请求的发出。
问题来了: 什么情况下请求会变成Preflighted Request呢?
*1. 请求方法不是`GET/HEAD/POST`;
2. HTTP请求头限制这几种字段,`人为设置该集合之外 `的其他首部字段:
`{Accept、Accept-Language、Content-Language、
Content-Type(需要注意额外的限制)、
DPR、Downlink、Save-Data、Viewport-Width、Width}`;
*3. POST请求的`Content-Type`并非:
`{
application/x-www-form-urlencoded,
multipart/form-data,
text/plain
}`;
4. 请求中的任意 `XMLHttpRequestUpload` 对象均有注册事件监听器;
*5. 请求设置了自定义的 `header` 字段;
6. 请求中没有使用 `ReadableStream` 对象;
header
信息: 用户登录的token信息放入header里面,也会触发。
大部分跨域发送的请求都是非简单请求,如何减少发起OPTIONS请求的次数?
-
后端在请求的返回头部添加: Access-Control-Max-Age:(number)
number代表:preflight request (预检请求)的返回结果可以被缓存多久,单位是秒
。(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) -
例如:将预检请求的结果缓存1分钟:Access-Control-Max-Age: 60
不同浏览器有不同的上限。在Firefox中,上限是24h(即86400秒),而在Chromium 中则是10min(即600秒)。Chromium 同时规定了一个默认值 5 秒。
如果值为 -1,则表示禁用缓存,每一次请求都需要提供预检请求,即用OPTIONS请求进行检测。
Access-Control-Max-Age
方法对完全一样的url的缓存设置生效,多一个参数也视为不同url。也就是说,如果设置了10分钟的缓存,在10分钟内,所有请求第一次会产生options请求,第二次以及第二次以后就只发送真正的请求了。
我们在虚拟的空间与你相遇,期待可以碰撞出不一样的火花
以上是关于Ajax中跨域请求为什么触发Options请求?的主要内容,如果未能解决你的问题,请参考以下文章