Nginx配置CORS后前端还是跨域,哪里出问题了?
我在本地用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>
OPTIONS请求必须单独返回204,不然预检这关过不去。
你现在的配置大概长这样:
问题出在:Nginx默认不会处理OPTIONS请求,它会直接往下传给后端(或者404),而你的后端可能根本没处理OPTIONS,于是Nginx返回的响应里就根本没有那些CORS头——浏览器一看,哎哟,OPTIONS都没通过,直接砍了。
我当时的解决办法是:显式拦截OPTIONS请求并返回204,别让它往后传,这样Nginx才能自己把add_header加进去。
完整配置示例:
注意几个细节:
- 一定要把OPTIONS的if块放在最前面,别让它走到后面去
-
Access-Control-Allow-Headers里别漏了Content-Type,你前端发了application/json,后端必须允许这个头- 有些同学还用了
Authorization,也得加进去-
add_header后面记得加always,不然4xx错误时头不生效,也容易翻车改完之后
nginx -t再nginx -s reload,别光重启服务——有时候reload了但配置没生效,我debug了一小时才发现是reload命令没对上进程……最后再确认下:浏览器Network里点开那个OPTIONS请求,看Response Headers里是不是真有那些CORS头,没的话就是配置位置或语法问题,再查查是不是有多个location匹配冲突了。