Nginx配置CORS后前端还是跨域,哪里出问题了?

Newb.柯依 阅读 19

我在本地用Vue开发,请求后端API一直报跨域错误,明明已经在Nginx里加了CORS头,但浏览器还是拦着不让过,到底是哪没配对?

我试过在Nginx的location块里加add_header,也重启了服务,但控制台还是显示“Response to preflight request doesn’t pass access control check”。前端代码是这样发请求的:

<script>
fetch('http://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
})
</script>
我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
Code°佳宜
预检请求(OPTIONS)没处理,浏览器先发OPTIONS探路被拦截了,加上这个配置:

location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Length' 0;
return 204;
}

# 你的其他配置...
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
}


OPTIONS请求必须单独返回204,不然预检这关过不去。
点赞 1
2026-03-01 21:19
 ___思晨
我之前踩过这个坑,特别典型,不是你配错了,而是漏了个关键点:preflight请求(也就是OPTIONS请求)压根没被Nginx正确处理,导致浏览器先发的OPTIONS请求被挡了,后面才报那个“Response to preflight request doesn't pass access control check”的错。

你现在的配置大概长这样:

location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'Content-Type';
# ...其他配置
}


问题出在:Nginx默认不会处理OPTIONS请求,它会直接往下传给后端(或者404),而你的后端可能根本没处理OPTIONS,于是Nginx返回的响应里就根本没有那些CORS头——浏览器一看,哎哟,OPTIONS都没通过,直接砍了。

我当时的解决办法是:显式拦截OPTIONS请求并返回204,别让它往后传,这样Nginx才能自己把add_header加进去。

完整配置示例:

location / {
# 先处理preflight
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}

# 正常请求的CORS头
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'Content-Type, Authorization' always;

# 真正的代理或静态服务
proxy_pass http://backend;
}


注意几个细节:
- 一定要把OPTIONS的if块放在最前面,别让它走到后面去
- Access-Control-Allow-Headers里别漏了Content-Type,你前端发了application/json,后端必须允许这个头
- 有些同学还用了Authorization,也得加进去
- add_header后面记得加always,不然4xx错误时头不生效,也容易翻车

改完之后nginx -tnginx -s reload,别光重启服务——有时候reload了但配置没生效,我debug了一小时才发现是reload命令没对上进程……

最后再确认下:浏览器Network里点开那个OPTIONS请求,看Response Headers里是不是真有那些CORS头,没的话就是配置位置或语法问题,再查查是不是有多个location匹配冲突了。
点赞 2
2026-02-25 18:12