add_header在Nginx中不生效主因是作用域限制、未加always参数及OPTIONS预检未兜底;需写入对应location块、启用always、显式处理OPTIONS并配全CORS头。

为什么 add_header 在 Nginx 里不生效?
宝塔面板里点“Nginx 配置” → “添加 Header”,填了 Access-Control-Allow-Origin: * 却没反应,大概率是被子请求或 location 块覆盖了。Nginx 的 add_header 不继承、不叠加,只在当前作用域生效,且对 301/302、error_page、内部重定向响应默认不生效。
- 必须写在
server块顶层,或明确写进你实际处理接口的location块里(比如location /api/) - 如果用了反向代理(如
proxy_pass),得确保后端没返回同名 header,否则 Nginx 默认不覆盖 - 想对所有响应(包括错误页)加跨域头,得加
always参数:add_header Access-Control-Allow-Origin "*" always;
宝塔界面填错位置:Add Header 设置在哪才管用?
宝塔的「网站」→「设置」→「配置文件」里有两个地方能加 Header:一个是顶部「Nginx 配置」里的「添加响应头」,另一个是底部「配置修改」手动编辑。前者只作用于根 location /,后者才能精准控制范围。
- 静态资源(HTML/JS/CSS)和 API 接口跨域需求不同,别一股脑全塞到全局 Header 框里
- 前端调的是
/api/v1/user,就在配置文件中找到对应location /api/块,在里面手写add_header - 宝塔自动生成的配置里可能已有
location ~ .*\.(js|css|png|jpg)$这类规则,这些 location 默认不继承 server 级 header,必须单独加
跨域必需的几个 header 怎么配全?
只加 Access-Control-Allow-Origin 常常不够,尤其前端用了 credentials: true 或自定义 header(如 Authorization),后端会预检失败。
-
Access-Control-Allow-Origin:值不能为*+Access-Control-Allow-Credentials: true同时存在,必须指定具体域名,比如https://example.com -
Access-Control-Allow-Methods:至少包含实际用到的动词,GET, POST, OPTIONS是基础,别漏掉OPTIONS(预检请求靠它) -
Access-Control-Allow-Headers:前端带了什么自定义 header,这里就得列什么,比如Content-Type, Authorization, X-Requested-With - 务必加
Access-Control-Max-Age(如86400),减少重复预检请求
add_header Access-Control-Allow-Origin "https://example.com" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" always; add_header Access-Control-Allow-Credentials "true" always; add_header Access-Control-Max-Age "86400" always;
OPTIONS 预检请求 502 或直接 404 怎么办?
浏览器发 OPTIONS 请求时,如果 Nginx 没匹配到任何 location,或匹配到了但没处理逻辑(比如 proxy_pass 指向了一个不支持 OPTIONS 的后端),就会挂掉。
- 最稳做法:在 API 对应的
location块里显式拦截 OPTIONS:if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; add_header Access-Control-Allow-Credentials "true"; return 204; } - 别依赖后端处理 OPTIONS,很多 PHP/Node 框架默认不响应它
- 宝塔自带的「反向代理」功能如果启用了,检查代理规则是否把 OPTIONS 请求也转发了——通常不该转,直接由 Nginx 短路响应更可靠
跨域不是加一两个 header 就完事,关键在请求路径、HTTP 方法、凭证状态三者对齐;最容易忽略的是 always 参数和 OPTIONS 的显式兜底,不加这两条,多数真实场景都会卡在预检阶段。











