起因
前两天在做 vue 项目的过程中使用 axios 做接口数据请求, 很普通的一个接口, 开发的过程中也没什么问题. 自测的时候郁闷的发先, 每个接口都调了两次, 刚开始没太注意感觉两次请求是一摸一样的, 仔细看了一圈, 发现第一次调用的 Request Method: OPTIONS , 第二次调用的 Request Method: POST . 并且 OPTIONS 的请求也损耗了很多的资源.
试想一下, 如果每个接口都这样调用两次, 在前端需要多损耗多少资源, 这个在复杂项目中的损耗是不可估量的. 于是就查了一番资料, 看到了很多不同的解决方法, 说一下我解决这个问题的方法和问题原因.
解决方案
1. 使用 URLSearchParams
- var params = new URLSearchParams()
- params.append('param1', 'value1')
- params.append('param2', 'value2')
这里的 params 就是正确请求接口入参, 这样的操作太复杂了, 每次都要这样生成入参数据, 实在太累 OUT
2. 使用 qs.stringify
安装 qs
NPM install --save qs
axios 配置
我这里把 axios 的封装写在了 src/plugins/Ajax.JS
- import axios from 'axios'
- import qs from 'qs'
- // 添加响应拦截器
- axios.interceptors.request.use(
- config => {
- if (config.method === 'post') {
- config.data = qs.stringify(config.data)
- }
- return config
- },
- error => {
- console.log(error)
- Promise.reject(error)
- }
- )
这里我们看一下, 其实就是在 axios 发起请求的前拦截请求, 当请求类型是 post 的时候, 把请求的入参数据 qs.stringify 一下, 看一下前后数据格式的对比.
- // qs.stringify 前
- {
- "userId": "520b0ec329164dd9a4f216ba8d209029",
- "startTime": "1548950400000",
- "endTime": "1551369599999"
- }
- // qs.stringify 后
- "userId=520b0ec329164dd9a4f216ba8d209029&startTime=1548950400000&endTime=1551369599999"
这时候再去看后台我发起的请求, OPTIONS 已经不存在啦, 只发起了一次正常的 post 请求
但是遗憾的是, 虽然接口请求类型正确了, 但是接口返回的数据错了, 接口提示没有获取到正确的入参数据, 跟后端的同学一起看了下, 应该是入参的数据类型从 JSON 变成的 string , 后端无法正确获取到, 这里就需要后端的同学获取入参格式化一下获取到的数据. 这样一切就搞定了.
3. 使用 Access-Control-Max-Age
这里说一个最简单的解决方法, 只要后端同学在设置跨域请求数据的时候, 添加 Access-Control-Max-Age , 这个参数的意思是把 OPTIONS 缓存起来, 在指定的时间内, 不会再次发起 OPTIONS 预请求, 这样只有在第一次请求的时候会有 OPTIONS , 如果这个时间拉的足够长, 其实并不太损耗资源, 这算是一个迂回解决的方法.
- // 后端设置, 2592000 单位秒, 这里是 30 天
- response.addHeader( "Access-Control-Max-Age", "2592000" )
在控制台开启 Disable cache, 可以看到请求中还有 OPTIONS , 关闭 Disable cache 之后, 再看请求已经没有了 OPTIONS
以上就是我们在 axios 中如果遇到复杂请求 OPTIONS 时候的几种解决办法, 请各位多指教.
来源: https://juejin.im/post/5c68b2efe51d457fd52ee155