nginx中配置cors需在目标api的location块内精准设置:添加access-control-allow-origin等头并配always参数,用if处理options预检返回204,带credentials时origin不能为*且须设allow-credentials为true,并用expose-headers声明前端可读响应头。

在 Nginx 的 location 块中配置 CORS,核心是精准控制、只对目标 API 路径生效,并正确处理预检请求。不能全局加头,也不能漏掉 OPTIONS 响应。
只在目标 API location 中添加头
把所有 CORS 相关的 add_header 指令写在具体代理路径的 location 块内,比如 location /api/ { ... }。这样能确保只有接口响应带跨域头,静态资源、健康检查等路径不受影响。
- ✅ 正确示例:
location /api/ { proxy_pass http://backend:8000/; add_header 'Access-Control-Allow-Origin' 'https://your-fe.com' always; ... } - ❌ 错误做法:把
add_header放在server或根location / { ... }里,会导致/favicon.ico、/health等也带上 CORS 头,干扰监控或 CDN 缓存
必须显式处理 OPTIONS 预检请求
浏览器对带自定义 Header 或非简单方法的请求,会先发一个 OPTIONS 请求。Nginx 默认不拦截,需手动返回 204 空响应。
- 在同一个
location块里,用if ($request_method = 'OPTIONS') { ... return 204; } - 所有 CORS 头(如
Allow-Origin、Allow-Methods)都要在if块里重复写一遍,并加上always参数,否则 204 响应里不会包含这些头 -
return 204必须放在最后,且不能被proxy_pass或其他指令覆盖
带凭证时的硬性要求
如果前端设置了 credentials: 'include'(比如传 Cookie 或 Authorization),后端必须满足三项:
-
Access-Control-Allow-Origin不能是*,必须写成具体域名,例如https://app.example.com -
Access-Control-Allow-Credentials设为true - 同时要在
add_header中显式列出所有前端发送的自定义请求头,比如X-Trace-ID、X-User-Token,否则会被浏览器拦截
透传响应头给前端
后端返回的某些响应头(如 X-Total-Count、X-Request-ID),默认前端 JavaScript 是读不到的。需要主动声明暴露:
- 用
add_header 'Access-Control-Expose-Headers' 'X-Total-Count, X-Request-ID' - 只列真正需要被 JS 读取的头,敏感头如
Set-Cookie即使写了也不会暴露 - 这个指令也建议加
always,保证在各种状态码下都生效











