nginx location块中配置跨域需用add_header注入cors头,access-control-allow-origin必须为具体可信域名(不可用*),配合always参数、options预检拦截及proxy_pass代理,确保安全与兼容。

在 Nginx 的 location 块中设置跨域请求允许的域名,核心是通过 add_header 指令注入标准 CORS 响应头,并确保 Access-Control-Allow-Origin 的值为具体、可信的前端域名(不能是 *,若需携带 Cookie)。
以下是最常用且安全的做法:
在 location 块中精准配置指定域名跨域
适用于只允许某个前端域名(如 https://admin.example.com)访问 API 接口(如 /api/ 路径)的场景:
location ^~ /api/ {
# 允许指定前端域名跨域(必须协议+域名完整,不能省略 https://)
add_header 'Access-Control-Allow-Origin' 'https://admin.example.com' always;
# 允许的 HTTP 方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
# 允许的请求头(按实际前端发送的自定义头补充)
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
# 若前端需携带 Cookie 或认证信息,必须开启且 Origin 不能为 *
add_header 'Access-Control-Allow-Credentials' 'true' always;
# 可选:暴露给前端的响应头(如自定义分页字段)
add_header 'Access-Control-Expose-Headers' 'X-Total-Count, Content-Length' always;
# 预检请求单独处理,避免返回空体导致 502 或浏览器拒绝
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# 正常代理到后端服务
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
注意事项和关键细节
-
Access-Control-Allow-Origin只能写一个域名,不支持逗号分隔或多个add_header;如需支持多个域名,必须用$http_origin动态匹配(需配合map指令,超出基础配置范围)。 -
always参数很重要:它确保即使后端返回 3xx/4xx/5xx 状态码,CORS 头仍会被添加(否则默认只对 2xx/3xx 生效)。 -
OPTIONS请求必须显式拦截并return 204,否则可能被透传给后端,而多数后端不处理 OPTIONS,导致跨域失败。 - 如果前端地址含端口(如
http://localhost:8080),Origin 必须严格匹配,包括端口;生产环境建议统一用域名,避免端口差异引发问题。
不推荐的写法(常见误区)
- ❌
add_header 'Access-Control-Allow-Origin' '*'
→ 仅适用于无需凭证(Cookie/Auth)的简单场景;一旦加了Access-Control-Allow-Credentials true,该写法会直接被浏览器拒绝。 - ❌ 在
server块顶层写跨域头却未限定路径
→ 可能意外暴露静态资源或管理接口的 CORS 权限,存在安全隐患。 - ❌ 忘记
always或漏掉OPTIONS处理
→ 导致部分请求(尤其是带 Authorization 的 POST)预检失败,控制台报错 “No 'Access-Control-Allow-Origin' header”。
配置完成后,记得执行 nginx -t 测试语法,再 nginx -s reload 重载生效。











