Nginx配置CORS后前端还是报跨域错误怎么办?

码农彦森 阅读 45

我在本地用React调后端API,后端部署在另一台服务器上。已经在Nginx里加了CORS头,但浏览器还是报跨域错误,不知道哪里没配对。

这是我的请求代码:

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ key: 'value' })
})
.then(res => res.json())
.then(data => console.log(data));

Chrome控制台显示:Access to fetch at ‘https://api.example.com/data’ from origin ‘http://localhost:3000’ has been blocked by CORS policy… 看起来预检请求都没过,是不是Nginx漏了什么配置?

我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
百里艳苹
这种情况我之前也遇到过,Nginx配置CORS没生效十有八九是预检请求(OPTIONS)没处理好。

你大概率只加了简单的CORS头,但没处理预检请求。预检请求需要返回特定的响应头,浏览器才会放行正式请求。

在Nginx的server块里试试这样配置:

#预检请求直接返回204和必要的头
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Max-Age' 86400 always;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
return 204;
}

# 正式请求加CORS头
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}


几个容易踩的坑提醒一下:

那个always参数一定要加,不加的话如果响应码不是2xx,CORS头不会返回。Access-Control-Allow-Origin改成你前端的实际地址,或者用变量动态获取$http_origin也行,但生产环境建议还是限定具体域名。

如果你前端请求带了cookie或者自定义头(比如Authorization),还得加Access-Control-Allow-Credentials头,并且Access-Control-Allow-Origin不能是通配符*,得是具体域名。

改完配置记得nginx -s reload重载一下,然后清浏览器缓存再试。
点赞
2026-03-19 19:18
令狐维通
这问题我太熟了,CORS配置经常让人头大。你这种情况多半是Nginx没处理好OPTIONS预检请求。

先确认你的Nginx配置里是不是少了这些关键项:

location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000';
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}

add_header 'Access-Control-Allow-Origin' 'http://localhost:3000';
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
}


注意几个要点:
1. 必须单独处理OPTIONS方法
2. 允许的Origin要明确写出来,不能直接写*
3. 允许的Headers要包含你JS里面实际发送的header(这里是Content-Type)

另外检查下你fetch请求是不是没加credentials配置。如果是带cookie的请求,Nginx还要加:
add_header 'Access-Control-Allow-Credentials' 'true';
JS里面fetch要加:
credentials: 'include'

配完记得nginx -t测试配置,nginx -s reload重载。
点赞
2026-03-09 23:01