问题
使用axios请求接口时,出现了发出两次请求的情况;一个是请求OPTIONS,一个是正常的POST请求;查资料发现与跨域请求有关。
概念
MDN中有提到:
出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。
跨域资源共享标准允许在下列场景中使用跨域 HTTP 请求:
- 前文提到的由
XMLHttpRequest
或 Fetch 发起的跨域 HTTP 请求。 - Web 字体 (CSS 中通过
@font-face
使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。 - WebGL 贴图
- 使用
drawImage
将 Images/video 画面绘制到 canvas - 样式表(使用 CSSOM)
而在页面中通过src或者href嵌入cdn文件或者图片之类的可以直接引入不会遵循CORS。
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET
以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST
请求),浏览器必须首先使用 OPTIONS
方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
简单请求不会触发CORS预检请求,而非简单请求则会触发
若请求满足所有下述条件,则该请求可视为“简单请求”,否则为非简单请求:
- 使用下列方法之一:GET POST HEAD
- Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type
()DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Type
的值仅限于下列三者之一:text/plain
multipart/form-data
application/x-www-form-urlencoded
- 请求中的任意
XMLHttpRequestUpload
对象均没有注册任何事件监听器;XMLHttpRequestUpload
对象可以使用XMLHttpRequest.upload
属性访问。 - 请求中没有使用
ReadableStream
对象。
解决办法
检查多余的请求头部:后台管理统有登录用户,登录后请求接口都会加一个自定义的头部token,每次请求都会带上让后台校验是否为当前用户或者token是否过期,当删除请求的token时,没有出现预请求。正常请求一次,加上token则会再次出现两次请求。
axios设置默认的Content-type为简单请求规定的三者之一。
引入qs模块,axios请求时添加qs序列化
后台设置 Access-Control-Max-Age(number) 。数值代表preflight request (预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 可以被缓存多久,单位是秒。
例如:将预检请求的结果缓存10分钟(但该方法第一次请求还是会发起一次option)
Access-Control-Max-Age: 600