昨天,群里的一位群友 资深全栈开发无霜 讨论了这个问题,我就想起来我平时也经常遇到这样的现象,但是我忽略了,今天 Mark 一下。
有时候,前端明明只发起了一次 post
请求,但是后端却会收到 2 次请求,其中一个是 option
请求
原因
跨域分为简单跨域请求和复杂跨域请求
简单跨域请求是不会发送 OPTIONS
的,请求的复杂跨域请求才会发送一个预检请求 OPTIONS
复杂跨域请求要满足以下:
- 请求方式不是
GET
、POST
、HEAD
POST
请求的 Content-Type
并非 application/x-www-form-urlencoded
, multipart/form-data
, 或 text/plain
- 请求设置了自定义
header
字段
解决方法
如果不想发送 option 请求可以改为简单请求
比如你的 Content-Type
可能是 application/json 格式,将其改为 application/x-www-form-urlencoded
- 不设置自定义请求头
Content-Type
设置为 application/x-www-form-urlencoded
1 2
| axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
|
- 把 json 格式的 data 参数用 qs 序列化成字符串;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import axios from "axios"; import config from "@/config"; import * as util from "utils/common"; import qs from "querystring"; let localUser = util.session("token"); axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; const instance = axios.create({ timeout: config.timer.connTimeout * 1000, responseType: "json", withCredentials: false, });
instance.interceptors.request.use( function (config) { let data = config.data; if (data) { localUser && localUser.token && (data.token = localUser.token); } let request = {}; request.jsondata = JSON.stringify(data); request = qs.stringify(request); config.data = request; return config; }, function (error) { return Promise.reject(error); } );
instance.interceptors.response.use( function (response) { return response; }, function (error) { return Promise.reject(error); } );
export default instance;
|
- 其实我们没有必要去避免 OPTIONS 请求,在实际项目中未必都是简单请求,也不是所有预检请求都可以转为简单请求,只需要后台配合设置一下跨域响应头部就可以解决了。
1 2 3
| response.addHeader("Access-Control-Allow-Origin", "\*"); response.addHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE"); response.setHeader(“Access-Control-Allow-Headers”, “x-requested-with,Authorization,Content-Type”);
|
- 减少检查频率(方法由**资深全栈架构师ZJINH**提供)
1
| header( ' Access-Control-Max-Age', '600');
|
部分来源
备注
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS