为什么Axios发送POST请求时会额外触发204状态的preflight预请求?
preflight预请求相关问题解答
什么是preflight预请求
preflight是浏览器基于CORS(跨域资源共享)安全策略自动发起的OPTIONS类型的预检请求,仅在当前请求属于非简单请求时触发。
它的作用是提前向服务端确认:当前请求的源地址、请求方法、自定义请求头是否被服务端允许,只有预检请求返回成功(状态码多为204)后,浏览器才会发送真正的业务请求。
常见会触发预检请求的场景:
- 请求方法为PUT、DELETE、PATCH等非基础方法
- 自定义了
Authorization等不在安全范围内的请求头 - 请求的
Content-Type为application/json(不在application/x-www-form-urlencoded、multipart/form-data、text/plain这三类简单请求允许的Content-Type范围内)
如何避免这类预检请求
共有两种可行方案,可根据业务场景选择:
方案1:调整请求为简单请求,完全消除预检
将你的POST请求调整为符合简单请求规范的格式,修改Axios请求配置,将参数序列化为表单格式,同时指定Content-Type为application/x-www-form-urlencoded:
// 提前安装qs库用于序列化表单参数:npm i qs import qs from 'qs' async submit() { this.button = true; try { const response = await axios.post(`register`, qs.stringify(this.form), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); response.data.success == false ? console.log(response.data.message) : this.$router.push('/'); } catch (error) { let { errors } = error.response.data; this.button = false; this.errors = {}; Object.keys(errors).forEach(element => { this.errors[element] = errors[element][0]; }); } },
修改后请求符合简单请求规则,浏览器将不再发起preflight预检。
方案2:服务端配置预检缓存,减少预检频次
如果业务必须使用application/json格式传参,可让后端在预检请求的响应头中添加Access-Control-Max-Age字段,值设置为缓存的秒数(例如86400代表缓存1天)。配置完成后,相同规则的请求的预检结果会被浏览器缓存,缓存有效期内不会重复发起预检请求。
注:你提供的截图中真实业务请求返回的404状态码与预检无关,属于接口路径或后端路由配置问题,需单独排查。
内容的提问来源于stack exchange,提问作者Mr.Singh
相关产品推荐
相关产品推荐

