使用axios配置Access-Control-Allow-Origin头发送POST遇CORS报错
核心错误原因拆解
1. 手动添加Access-Control-Allow-Origin请求头触发预检拦截
Access-Control-Allow-Origin是服务端返回给浏览器的响应头,从来不是客户端可以自定义的请求头。
你在请求头里塞这个字段时,会直接触发浏览器的CORS预检流程:浏览器会先向目标服务端发一个OPTIONS预请求,询问对方“现在客户端要带access-control-allow-origin这个头发正式请求,你允许不?”。绝大多数服务端的CORS配置里,根本不会把这个响应头加到允许的客户端请求头白名单里,所以直接返回预检失败,就会报你看到的"Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response"错误。
2. 参数位置错位导致数据结构异常
axios post方法的参数顺序是固定的:axios.post(url[, 请求业务数据[, 请求配置项]])
三个槽位的职责完全固定:
- 第一个槽位:请求目标URL
- 第二个槽位:POST请求要发的主体业务数据
- 第三个槽位:全局请求配置,headers、超时、鉴权参数都要放这里
你把data和headers的位置交换,本质是把本该放第三个槽位的配置对象,塞到了第二个槽位的业务数据位置,axios会把这整个配置对象直接当POST的body发出去,自然就会出现data: "{"headers":{"Access-Control-Allow-Origin"这种嵌套错误的结构。
另外你原代码里第二个参数写的{ data: sendData }本身也有问题:这种写法会让实际提交的body多套一层data字段,和接口预期的平层数据结构对不上,就算请求正常发出去,也会因为格式不对被后端拒绝。
具体解决步骤
- 立刻删掉手动加的
Access-Control-Allow-Origin请求头
这个头根本没有客户端设置的逻辑,加了不仅解决不了跨域,还会直接触发预检报错。跨域的权限判定完全由目标服务端的CORS配置说了算,客户端没有任何权限主动声明自己能跨域访问。 - 严格按照参数顺序传值,不要错位
修正后的可运行代码如下:axios .post( data.submissionUrl, sendData, // 直接把业务数据放第二槽位,不要额外套一层data { // 第三槽位放请求配置,只加接口要求的合法请求头 headers: { "Content-Type": "application/json" } } ) .then((response) => { console.log(response); }) .catch((err) => { console.log(err, err.response); }); - 修正后依然遇到跨域拦截的处理方式
如果删了错误头、修正了参数位置还是被CORS拦,说明目标服务端根本没配置允许你当前本地开发环境(也就是VSCode Live Server对应的本地地址源)跨域访问,这时候别想着在客户端代码里瞎加头“破解”,正确的处理方式是:- 找接口提供方,把你的本地开发源加到服务端的CORS白名单里
- 本地开发阶段用代理转发的方式绕过浏览器的跨域限制
内容的提问来源于stack exchange,提问作者V.Cunichin
相关产品推荐
相关产品推荐

