Node.js通过Nginx反向代理部署时跨域头丢失,主因是Nginx默认不透传Origin等关键头;需逐层显式透传、统一由Nginx管控CORS响应头、禁用后端自动注入,并妥善处理302重定向与OPTIONS预检。

Node.js 应用通过 Nginx 反向代理部署时,跨域请求的头丢失问题,核心不是 Nginx “删了头”,而是它默认不主动透传某些关键请求头(尤其是 Origin),且多级转发或重定向场景下容易中断传递链。解决的关键在于:**逐层显式透传 + 统一管控 CORS 响应头 + 避免后端重复注入**。
确保 Origin 头完整透传到 Node.js
Origin 是浏览器发起跨域请求时自动携带的标准头,但 Nginx 不会自动把它转发给后端——必须手动声明:
- 在每个涉及代理的
location块中添加:proxy_set_header Origin $http_origin; - 确认
proxy_pass_request_headers on;已启用(默认开启,但显式写出更稳妥) - 如果用了灰度或内部定制头(如
gray_origin),需额外开启:underscores_in_headers on;,再加一行:proxy_set_header gray_origin $http_gray_origin;
禁止后端自行设置 CORS 响应头
Node.js(如 Express 的 cors() 中间件)若也返回 Access-Control-Allow-Origin,和 Nginx 的响应头叠加会导致冲突,Nginx 报错或浏览器拒绝响应:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 关闭 Express 中所有自动 CORS 注入,例如移除
app.use(cors())或设为仅开发环境启用 - 让最外层 Nginx 统一控制跨域策略,例如用
map实现白名单校验:map $http_origin $cors_origin {<br> default "";<br> "https://your-app.com" "https://your-app.com";<br> "https://staging.app.com" "https://staging.app.com";<br>}
再在 location 中:add_header 'Access-Control-Allow-Origin' $cors_origin always;<br>add_header 'Access-Control-Allow-Credentials' 'true' always;
处理 302 重定向导致的跨域断裂
Node.js 返回 302 后,浏览器会发起全新跨域请求访问 Location 地址,此时 Origin 丢失、CORS 头缺失——这不是头“丢了”,而是浏览器对跳转后请求重新做 CORS 校验:
- 在 Nginx 中拦截 302:
proxy_intercept_errors on;<br>error_page 301 302 = @handle_redirect;
- 在
@handle_redirect中重写跳转并补全 CORS 头:@handle_redirect {<br> add_header 'Access-Control-Allow-Origin' '$http_origin' always;<br> add_header 'Access-Control-Allow-Credentials' 'true' always;<br> return 302 $sent_http_location;<br>} - 同时用
proxy_redirect修正内网地址,例如:proxy_redirect http://127.0.0.1:3000/ /api/;
预检请求(OPTIONS)必须被正确响应
前端发非简单请求前会先发 OPTIONS,若这个请求被重定向(比如 HTTP → HTTPS 全局跳转)或没匹配到规则,就会失败:
- 在 Nginx 的
location中提前拦截 OPTIONS:if ($request_method = 'OPTIONS') {<br> add_header 'Access-Control-Allow-Origin' '$http_origin' always;<br> add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;<br> add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;<br> add_header 'Access-Control-Allow-Credentials' 'true' always;<br> return 204;<br>} - 确保该逻辑在任何重定向或 rewrite 规则之前执行

















