在 nginx 中配置跨域 cors 响应头,核心做法是在 `location` 块内使用 `add_header` 指令添加 `access-control-allow-origin`、`access-control-allow-methods` 和 `access-control-allow-headers`。这样做能让浏览器识别当前请求是合法的跨域请求,从而允许前端代码获取后端数据。若遇到预检请求(options)被拦截的情况,需额外配置对 options 请求的直接返回逻辑,确保状态码为 204 且包含完整的权限头。

如何配置基础 CORS 响应头
基础配置只需在对应的 location 块中添加三个关键头部:来源白名单、允许的 HTTP 方法以及允许的请求头。这能解决大多数简单的 GET 或 POST 跨域请求。

server {
listen 80;
server_name api.example.com;
location /api/ {
# 允许特定来源访问,* 表示允许所有来源(生产环境建议指定域名)
add_header Access-Control-Allow-Origin "https://frontend.example.com" always;
# 允许的 HTTP 方法
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
# 允许的自定义请求头
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;
# 实际业务代理或处理逻辑
proxy_pass http://backend_server;
}
}
上述配置中,`always` 参数至关重要,它确保即使 Nginx 返回错误页面(如 404 或 500),CORS 头也会一并发送,避免浏览器因缺少头信息而报错。`Access-Control-Allow-Origin` 指定了谁可以发起请求,`Access-Control-Allow-Methods` 列出了允许的动词,`Access-Control-Allow-Headers` 则涵盖了前端可能发送的非标准头,如 `Authorization` 用于身份验证。
如何处理预检请求 OPTIONS
当请求包含非简单方法(如 PUT、DELETE)或自定义头时,浏览器会先发送一个 OPTIONS 预检请求。Nginx 必须直接响应这个请求并返回 204 No Content,否则后续的实际请求会被浏览器阻止。

server {
listen 80;
server_name api.example.com;
location /api/ {
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://frontend.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;
add_header Access-Control-Max-Age 1728000; # 预检结果缓存时间,单位秒
add_header Content-Type "text/plain charset=UTF-8";
add_header Content-Length 0;
return 204;
}
# 处理实际请求
add_header Access-Control-Allow-Origin "https://frontend.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;
proxy_pass http://backend_server;
}
}
在 `if` 块中,我们专门捕获 `OPTIONS` 请求。`Access-Control-Max-Age` 告诉浏览器预检结果的有效时长,减少重复预检开销。返回 204 状态码表示成功但无内容,符合预检请求的规范。注意,`if` 指令在 Nginx 中需谨慎使用,但在处理 OPTIONS 预检时是标准且推荐的做法。实际请求部分保留原有的 CORS 头设置,确保正常流程不受影响。
基于 Access-Control-Allow-Credentials 的具体问题
当需要携带 Cookie 或凭证进行跨域请求时,必须将 `Access-Control-Allow-Credentials` 设置为 `true`,同时 `Access-Control-Allow-Origin` 不能设为 `*`,必须明确指定具体域名。这是由浏览器安全策略强制规定的,违反此规则会导致请求失败。
在实际开发中,开发者常误以为设置 `*` 即可兼容所有情况,但一旦启用凭证模式,浏览器会拒绝任何通配符来源。因此,配置时需确保前后端域名严格匹配,并在前端 JS 中开启 `withCredentials: true`。例如,若前端域名是 `https://app.example.com`,后端 Nginx 配置应为 `add_header Access-Control-Allow-Origin "https://app.example.com" always;` 并追加 `add_header Access-Control-Allow-Credentials true;`。这样既满足了安全要求,又实现了凭证传递。


















