Nginx跨域配置必须在匹配API的location块内显式添加add_header,因该指令不继承且if中无效;带凭证时Origin不能为*,须动态匹配可信域名并配Access-Control-Allow-Credentials:true,且OPTIONS预检需独立响应204并携带全部CORS头。

直接加 add_header 不生效,是因为 Nginx 的响应头继承规则和 location 作用域限制导致的——你加的位置不对,或者被后续配置覆盖了。
为什么在 server 块里加了 CORS 头还是跨域失败?
Nginx 中 add_header 指令**不会继承到子 location 块中**。如果你的前端是静态资源(/),后端 API 走 /api/,而你只在 server 块里写了 add_header,那么所有请求(包括 OPTIONS 预检)都可能收不到这些头——尤其是当请求命中某个 location ^~ /api/ 块时,它会忽略父块的 add_header,除非你显式再写一遍。
- 浏览器发
OPTIONS请求时,Nginx 默认不返回任何 CORS 头,除非该location显式配置了add_header - 如果用了
try_files或index跳转,响应可能由内部重定向触发,add_header在原始 location 失效 -
add_header在if块里会被完全忽略(Nginx 官方明确禁止)
怎么让 /api/ 接口真正支持带凭证的跨域?
必须同时满足三个条件:Origin 白名单、Credentials 开关、预检响应完备。不能用 * 配合 Access-Control-Allow-Credentials true,这是浏览器直接拒绝的组合。
- 把
Access-Control-Allow-Origin设为具体域名,比如https://myapp.com,而不是* - 显式添加
add_header 'Access-Control-Allow-Credentials' 'true';到处理 API 的location块内 - 确保
OPTIONS请求能被正确响应:加一个location = /api/或通配location ~ ^/api/.*$,并在其中包含完整的预检头 - 注意
proxy_pass后端时,后端服务本身也**不能**再返回 CORS 头,否则可能冲突(推荐只由 Nginx 统一控制)
如何避免跨域配置污染静态资源?
给根路径 / 加 CORS 头是没意义的,还可能暴露敏感 header。应该严格按路径隔离,只对 API 路径生效。
- 不要在
server块顶层加全局 CORS 头 - 为 API 单独建
location ^~ /api/块,并在里面写全add_header;静态资源走默认location /,不加任何 CORS 相关头 - 如果前端用 Vue Router history 模式,
location /里已有try_files $uri $uri/ /index.html;,别让它和 API location 冲突——确保^~ /api/的优先级高于/ - 检查最终生效的配置:执行
nginx -t验证语法,再nginx -s reload,最后用curl -I https://yoursite.com/api/test看响应头是否包含预期字段
最常被忽略的一点:Nginx 的 add_header 在 301/302 重定向响应中默认不生效,如果你的 API 网关或后端做了跳转,CORS 头就丢了——这种情况下得用 always 参数:add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;。











