使用 proxy_hide_header 可屏蔽后端 CORS 头,避免与 Nginx add_header 冲突导致浏览器拒绝请求;需配合 always 参数的 add_header 统一注入规范 CORS 头,并显式拦截 OPTIONS 请求返回 204 确保预检通过。

使用 proxy_hide_header 可以有效屏蔽后端响应中不必要或与 Nginx 自身设置冲突的跨域相关响应头(如 Access-Control-Allow-Origin),从而避免浏览器因收到重复/矛盾的 CORS 头而拒绝请求。
为什么会出现跨域头部重复冲突?
常见于以下场景:
- 后端服务(如 Node.js、Spring Boot)已自行设置了
Access-Control-Allow-Origin: *等 CORS 头; - Nginx 反向代理层又通过
add_header显式添加了相同的头(例如统一配置全局 CORS); - 浏览器收到两个
Access-Control-Allow-Origin响应头(或值不一致),直接判定为非法响应,报错Response to preflight request doesn't pass access control check。
用 proxy_hide_header 屏蔽后端原始 CORS 头
在 Nginx 的 location 或 server 块中,加入:
proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Expose-Headers;
这样 Nginx 在转发响应给客户端前,会主动移除后端返回的这些头,确保只有 Nginx 自己通过 add_header 设置的一份权威 CORS 头生效。
配合 add_header 统一控制跨域策略
屏蔽后端头之后,必须由 Nginx 主动注入规范、可控的 CORS 响应头:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always; add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always; add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always; add_header Access-Control-Allow-Credentials "true" always;
注意:务必加上 always 参数,否则 Nginx 默认只对 2xx/3xx 响应添加头,会导致 OPTIONS 预检请求(返回 204)不带 CORS 头而失败。
处理预检请求(OPTIONS)的特殊逻辑
仅靠 proxy_hide_header + add_header 不足以完全解决预检问题。建议显式拦截并短路 OPTIONS 请求:
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Max-Age 1728000;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}这段代码放在 location 块内,可避免将 OPTIONS 请求透传给后端,减少不必要的处理开销,并确保预检响应头 100% 可控。










