跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何通过 Nginx 配置 add_header always 解决 405 状态码下 CORS 头不生效问题

加always参数可解决405响应缺CORS头问题,但仅当405由Nginx自身返回时有效;若由后端返回或为内置错误页,则需拦截OPTIONS请求return 204或用error_page 405=200重写。 直接加
always
就能解决 405 响应里缺 CORS 头的问题,但前提是:这个 405 真的是 Nginx 自己返回的,而不是后端服务返回后被 Nginx 转发出去的。 为什么 405 响应默认没有 CORS 头 Nginx 的
add_header
指令默认只对成功响应(2xx、3xx)生效。遇到 405 这类错误响应时,Nginx 不会自动添加你配置的头——哪怕你在
location
块里写了
add_header Access-Control-Allow-Origin "*"
,它也不会出现在 405 响应里。 这会导致两个实际问题: 前端发 OPTIONS 预检请求,Nginx 因路径不匹配或方法不支持直接返回 405,但没带 CORS 头,浏览器直接报错“preflight response has invalid HTTP status code” 漏洞扫描工具检测到 405 响应缺少安全头(如
Access-Control-Allow-Origin
),标记为风险项 add_header … always 的作用和写法
always
参数让
add_header
强制作用于所有响应,包括 4xx 和 5xx。这是最直接有效的修复方式。 正确写法示例:
location /api/ { proxy_pass http://backend; 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,Content-Type,Authorization' always; }
注意:
always
必须紧接在
add_header
后面,不能换行,也不能加引号包裹
always
。 但光加 always 可能还不够:先确认 405 是谁返回的 如果 405 是后端服务返回的(比如 Spring Boot 或 Node.js 接口不支持 OPTIONS),Nginx 默认只是透传响应,不会重写头。此时
add_header ... always
依然无效——因为 Nginx 不会修改已存在的响应头,除非你显式开启透传控制。 Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载 应对方法有两种: 推荐:在
location
块中拦截 OPTIONS 请求,主动 return 204(或 200),并在 if 块内加全 CORS 头(含
always
) 次选:启用
proxy_pass_request_headers on
并配合
add_header ... always
,但有安全风险,一般不建议 拦截写法示例:
location /api/ { 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,Content-Type,Authorization' always; add_header 'Access-Control-Max-Age' 1728000 always; add_header 'Content-Type' 'text/plain; charset=utf-8' always; add_header 'Content-Length' 0 always; return 204; } proxy_pass http://backend; add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Credentials' 'true' always; }
顺便解决 405 页面无法显示 CORS 头的连带问题 有些场景下,用户访问一个不存在的接口路径(如
/v1/xxx
),Nginx 因未配置对应
location
,回落到
/
块处理,而该块只允许 GET,导致返回 405。这时即使加了
always
,CORS 头也加不到错误页上——因为 405 响应由 Nginx 内置错误页机制生成,
add_header
对其无效。 稳妥做法是显式捕获并重写:
error_page 405 =200 $request_uri;
这句放在 server 或 http 块里,能让 405 被转成 200 后再走正常响应流程,
add_header ... always
就能生效了。

相关文章