问题本质是浏览器对重定向链每步独立校验CORS,导致302后新请求缺失Origin和跨域头;应通过Nginx拦截重定向、重写Location、透传X-Forwarded头并前置处理OPTIONS预检。

这个问题本质不是“头丢失”,而是浏览器对重定向链中每一步都独立校验 CORS。后端返回 302 后,浏览器会用全新请求访问 Location 地址,这个新请求不带 Origin、不继承原响应头,如果跳转目标没配好 CORS,就会失败。
让 Nginx 拦截并重写重定向(推荐)
不让 302 透传给浏览器,由 Nginx 自己完成跳转,并统一加跨域头:
- 启用拦截:
proxy_intercept_errors on; - 捕获状态码:
error_page 301 302 = @handle_redirect; - 在命名 location 中控制跳转并加头:
@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>}
修正 Location 响应头路径
后端生成的跳转地址常含内网地址或错误前缀,需用 proxy_redirect 重写:
- 相对路径补前缀(如代理在
/api/下):proxy_redirect / /api/; - 绝对地址替换:
proxy_redirect http://192.168.1.100:8080/ https://$host/api/; - 正则匹配多种内网 host:
proxy_redirect ~^http://[^/]+(?::\d+)?/(.*)$ https://$host/api/$1;
确保后端生成正确跳转地址
Nginx 只能兜底改头,治本要让后端知道自己被代理:
- 透传协议:
proxy_set_header X-Forwarded-Proto $scheme; - 透传原始 Host:
proxy_set_header Host $http_host; - 显式告知路径前缀(可选):
proxy_set_header X-Forwarded-Prefix /api/; - 后端需读取这些头,拼接跳转 URL,避免硬编码内网地址
预检请求别被重定向干扰
如果后端有 HTTP → HTTPS 全局跳转,它可能把 OPTIONS 预检也 301 了,浏览器直接报错:
- 确认后端中间件顺序:CORS 必须在 HTTPS 重定向之前启用
- 对 OPTIONS 请求提前返回 204,跳过所有重定向逻辑
- 或在 Nginx 层单独处理 OPTIONS:
if ($request_method = 'OPTIONS') { add_header ...; return 204; }


















