Ajax中跨域请求为什么触发Options请求?

Posted 前端大联盟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax中跨域请求为什么触发Options请求?相关的知识,希望对你有一定的参考价值。

茫茫人海中与你相遇

相信未来的你不会很差


来源:https://www.jianshu.com/p/578e23c2898c

浏览器将CORS请求分为两类:简单请求(simple request)和非简单请求(not-simple-request)。
简单请求浏览器请求不会触发预检请求,而非简单请求会触发预检请求
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` 对象;


PS: 发送POST请求:content-type: text/xml 或者application/json,就会发送OPTIONS预请求;或者自定义 header 信息: 用户登录的token信息放入header里面,也会触发。

大部分跨域发送的请求都是非简单请求,如何减少发起OPTIONS请求的次数?

  1. 后端在请求的返回头部添加: 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请求?

我们在虚拟的空间与你相遇,期待可以碰撞出不一样的火花


公众号ID:前端大联盟

扫码关注最新动态




以上是关于Ajax中跨域请求为什么触发Options请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何用CORS来解决JS中跨域的问题

当跨域时,js ajax 请求出现options请求

http options请求

ajax跨域请求

Vue项目中跨域问题的解决

怎样避免跨域发出OPTIONS请求?