React调用localhost本地API时fetch POST请求被CORS策略拦截
问题根因
你遇到的报错是两个问题共同导致的,Postman可以正常调用接口是因为Postman不受浏览器同源策略限制,不能作为接口符合浏览器调用规则的判断依据:
- 跨域拦截:前端服务运行在
http://localhost:3000,后端接口运行在http://127.0.0.1:8000,二者域名(localhost和127.0.0.1属于不同host)、端口都不一致,属于跨域请求。后端接口响应没有携带Access-Control-Allow-Origin相关CORS头,被浏览器安全策略拦截。 - 前端fetch代码存在语法错误,即使配置了CORS也无法正常按预期发送请求。
前端代码错误点
- 配置项拼写错误:fetch API中设置请求头的配置字段为
headers,你写的header缺末尾的s,自定义的请求头完全不会被带上。 - 请求头字段名错误:JSON请求的Content-Type头正确写法是
Content-Type,你写的Content Type中间是空格,属于无效HTTP头字段。 - 不规范的异步写法:函数标记为
async但内部没有使用await处理Promise,直接在then里打印拿到的是原始Response对象,不是接口返回的业务数据,需要调用解析方法才能拿到实际内容。
修复步骤
1. 修正前端请求代码
修正后的可运行代码:
const SubmitContact = async (e)=>{ e.preventDefault() const contact = {contact_name,contact_email,contact_body} const res = await fetch("http://127.0.0.1:8000/my-api/",{ method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json", }, body: JSON.stringify(contact) }) const result = await res.json() console.warn(result) }
2. 配置后端CORS规则
你需要在8000端口的后端服务中添加CORS配置:
- 给所有响应添加
Access-Control-Allow-Origin头,开发环境可以临时设置值为*允许所有来源访问,生产环境需要替换为实际的前端域名http://localhost:3000 - 因为你发送的
Content-Type: application/json的POST请求属于非简单请求,浏览器会先发送OPTIONS方法的预检请求,后端需要正确响应OPTIONS请求,允许POST方法、Content-Type等自定义请求头。
注意:不要通过设置fetch的
mode: 'no-cors'绕过报错,该模式下你无法读取接口返回的正常响应内容,只能拿到type为opaque的无效响应,完全无法满足业务需求。
内容的提问来源于stack exchange,提问作者hawaj
相关产品推荐
相关产品推荐

