CORS预检请求(Preflight request)

665 阅读2分钟

1、写在前面

在使用cors处理跨域问题时,我们有时候会出现两次请求的情况,第一次请求method为OPTIONS,第二次才会进行真实请求,我们称这种情况为预请求,也叫options请求,可用于检测服务器允许的 http 方法,它是浏览器的一种安全策略。

2、什么是预请求?

CORS把请求分为两类:简单请求和预检请求。

说起预请求我们要先来说说什么是简单请求:

2.1 什么是简单请求?

若请求同时满足所有下述条件,则该请求可视为“简单请求”:

1、请求的HTTP方法只能为 GETPOSTHEAD之一;

2、请求的HTTP头只能是AcceptAccept-LanguageContent-LanguageContent-Type

3、Content-Type 的值仅限于下列三者之一: text/plainmutipart/form-dataapplication/x-www-form-urlencoded

4、请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。

5、请求中没有使用 ReadableStream 对象。

2.2 什么是预请求?

任何一个不满足简单跨域请求要求的请求,即被认为是复杂请求,也称作预检请求

3、如何避免预请求?

预请求是浏览器的一种安全策略,但是它的存在给会占用浏览器的资源,影响页面的性能,所以要尽可能的减少options请求。而方法也很简单,使用简单请求即可:

注意以下几点:

  1. 而在日常开发中,比如Axios里面默认的content-typeapplication/json,这就需要将content-type修改成application/x-www-form-urlencoded即可。
  2. 如果是post请求的话,需要对参数做个处理,需要引用qs库,将qs.stringify将参数序列化进行传参。

如果以上没问题,但是还是有预请求的话,需要查看header里是否设置了其他参数,因为在项目开发中经常会将token放到header里进行传参,这种场景需要后端使用Access-Control-Max-Age

Access-Control-Max-Age的作用
用来指定本次预检请求的有效期,单位为秒,这样只有在第一次请求的时候会有options ,之后浏览器会从缓存里读取响应,也就不会再发送options请求。
Access-Control-Max-Age0表示每次异步请求都发起预检请求,也就是说,发送两次请求。
Access-Control-Max-Age1800表示隔30分钟才发起预检请求。

参考资料: www.jianshu.com/p/437e8d580…