Nginx 反向代理如何配置 CORS 跨域访问控制允许头信息

文章导读
Nginx 配置 CORS 跨域访问控制的核心是使用 add_header 指令在响应中注入 Access-Control 系列头信息,并在 location 块中单独处理 OPTIONS 预检请求。该方案适用于 Nginx 作为反向代理或静态资源服务器的场景,风险边界在于错误配置 Access-Control-Allow-Origin 为通配符且同时开启 Allow-Credentials 会导
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Nginx 配置 CORS 跨域访问控制的核心是使用 add_header 指令在响应中注入 Access-Control 系列头信息,并在 location 块中单独处理 OPTIONS 预检请求。该方案适用于 Nginx 作为反向代理或静态资源服务器的场景,风险边界在于错误配置 Access-Control-Allow-Origin 为通配符且同时开启 Allow-Credentials 会导致浏览器拒绝请求。

先说结论:Nginx 通过 add_header 指令直接添加 CORS 响应头,必须显式放行 OPTIONS 方法以避免预检请求失败。

  • 适合:Nginx 反向代理 API 接口或前端静态资源跨域访问场景
  • 先准备:确认前端请求的 Origin 域名、HTTP 方法及自定义 Header 列表
  • 验收:使用 curl 命令携带 Origin 头验证响应头是否完整返回

命令速用版

以下配置片段可直接放入 server 或 location 块中,注意根据实际域名修改 Access-Control-Allow-Origin 的值。

location / {
    proxy_pass http://backend;
    
    # 允许跨域源
    add_header Access-Control-Allow-Origin "https://example.com";
    # 允许跨域方法
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
    # 允许跨域头
    add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
    # 允许携带凭证
    add_header Access-Control-Allow-Credentials "true";
    
    # 处理预检请求
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin "https://example.com";
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
        add_header Access-Control-Max-Age 1728000;
        add_header Content-Type 'text/plain; charset=utf-8';
        add_header Content-Length 0;
        return 204;
    }
}

为什么会这样

浏览器出于安全策略,默认禁止跨域 HTTP 请求,除非服务器响应中包含特定的 CORS 头信息。

Nginx 作为反向代理时,后端服务可能未配置 CORS 头,或者 Nginx 缓存了不带 CORS 头的响应。通过在 Nginx 层统一注入头信息,可以确保客户端无论请求哪个后端节点都能收到一致的跨域许可。OPTIONS 预检请求是浏览器在发送复杂请求前自动发起的探测,若 Nginx 未对该方法返回 200 状态码及对应头信息,正式请求会被浏览器拦截。

分步处理

1. 编辑 Nginx 配置文件,通常位于 /etc/nginx/nginx.conf 或 /etc/nginx/conf.d/ 目录下。

Nginx 反向代理如何配置 CORS 跨域访问控制允许头信息

2. 在对应的 server 或 location 块中添加 add_header 指令,指定 Access-Control-Allow-Origin 为前端域名。

3. 增加 if 判断语句拦截 $request_method 为 OPTIONS 的请求,直接返回 204 状态码并携带 CORS 头。

4. 执行 nginx -t 检查配置语法,确认无误后执行 nginx -s reload 重载配置。

怎么验证是否生效

使用 curl 命令模拟带 Origin 头的请求,检查响应头中是否包含 Access-Control-Allow-Origin。

curl -v -H "Origin: https://example.com" -X OPTIONS https://your-nginx-domain.com

观察输出中是否有 < Access-Control-Allow-Origin: https://example.com 字段。同时在浏览器开发者工具的 Network 面板中,确认预检请求状态码为 200 或 204,且正式请求未报 CORS 错误。

常见坑

1. add_header 继承问题:在 if 块中使用 add_header 时,外部定义的 add_header 可能不会自动继承,需要在 if 块内重新定义所有需要的头。

Nginx 反向代理如何配置 CORS 跨域访问控制允许头信息

2. 通配符与凭证冲突:Access-Control-Allow-Origin 设置为 * 时,Access-Control-Allow-Credentials 不能设置为 true,否则浏览器会报错。

3. 缓存干扰:若 Nginx 开启了 proxy_cache,可能缓存了不带 CORS 头的后端响应,需配置 proxy_ignore_headers 或在 Nginx 层强制覆盖头信息。

常见问题

Access-Control-Allow-Origin 可以设置为星号吗

可以设置为星号表示允许所有域名,但如果需要携带 Cookie 等凭证信息,则必须指定具体域名且不能为星号。

为什么 OPTIONS 请求返回 403 或 404

通常是因为 Nginx 配置中未显式放行 OPTIONS 方法,或者后端服务拦截了该请求,需在 Nginx 层直接返回 204 避免请求透传到后端。

配置生效后浏览器仍报 CORS 错误怎么办

检查响应头是否真的返回,确认是否有重定向导致头信息丢失,并清除浏览器缓存后重试。

参考来源

  • MDN Web Docs: HTTP 访问控制 (CORS) - https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
  • Nginx Official Documentation: ngx_http_headers_module - https://nginx.org/en/docs/http/ngx_http_headers_module.html