nginx跨域配置add_header不生效主因是作用域限制、缺少always参数及options预检未处理;须在proxy_pass所在location块中显式配置,禁用*与credentials共存,并确保access-control-allow-headers明确列出前端实际发送的字段。

phpEnv 是 Windows 下的本地 PHP 环境套件,底层用的是 Nginx(非 Apache),所以跨域配置必须走 Nginx 的 add_header 指令,不能指望 PHP header() 函数兜底——尤其当请求被 Nginx 直接代理或缓存时,PHP 根本没机会执行。
为什么在 phpEnv 的 nginx.conf 里加 add_header 不生效?
常见现象:改了 nginx.conf,nginx -t 通过,也 reload 了,但浏览器 Network 面板里看不到 Access-Control-Allow-Origin 等头。
- phpEnv 默认把站点配置拆到
vhost/目录下单独文件(如vhost/www.test.com.conf),主nginx.conf里只做 include,你改错地方了 -
add_header不继承:如果请求命中了某个location ~ \.php$块,而 CORS 头只写在server块里,那它不会自动带过去 - phpEnv 自带的 PHP-FPM 配置常含
fastcgi_hide_header,会主动屏蔽 PHP 输出的 CORS 头(比如你写了header("Access-Control-Allow-Origin: *")),导致白写
正确位置:在 vhost 配置的 location /api/ 块内显式写
假设你的 API 接口路径是 /api/,前端地址是 http://localhost:3000,那就必须在对应 location 里补全所有 CORS 头,且 always 标志不能少:
location /api/ {
proxy_pass http://127.0.0.1:9000;
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS' 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' 'X-Total-Count,X-Request-ID' always;
<pre class="brush:php;toolbar:false;">if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}}
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
注意:always 是关键——没有它,Nginx 在 301/302 或错误响应时不会输出这些头;proxy_pass 后端若也返回同名头,建议加 proxy_hide_header 'Access-Control-Allow-Origin'; 避免冲突。
带 Authorization 或 Token 时,Access-Control-Allow-Headers 必须显式列出
浏览器发带 Authorization 或自定义 Token 头的请求,会触发预检;如果 Nginx 的 Access-Control-Allow-Headers 没包含它们,预检直接失败,控制台报 Request header field authorization is not allowed by Access-Control-Allow-Headers。
- 不能写成
add_header 'Access-Control-Allow-Headers' '*'—— 这个值不被标准支持,Chrome/Firefox 都无视 - 必须明确列出:比如前端发
Authorization和X-Trace-ID,这里就得写'Authorization,X-Trace-ID' - 大小写不敏感,但建议按惯例小写(
authorization、x-trace-id)更稳妥,避免某些旧客户端解析异常
开发阶段别碰 * + credentials 组合
phpEnv 是纯本地环境,很容易图省事写 Access-Control-Allow-Origin: * 并同时开 Access-Control-Allow-Credentials: true。这会导致浏览器静默拦截所有带 cookie 或 auth 的请求,连 console 都不报错,只显示 “Failed to fetch”。
真正要调试登录态跨域,必须:
- 前端 URL 用
http://localhost:3000(不是127.0.0.1),后端 Nginx 的Access-Control-Allow-Origin就写死这个 - 确保
withCredentials: true(fetch)或xhrFields: { withCredentials: true }(jQuery)已设 - 检查响应里有没有
Set-Cookie字段被后端返回——Nginx 不会过滤它,但浏览器只在 Origin 完全匹配时才带上 cookie 回传
动态匹配 Origin 虽然更安全,但在 phpEnv 这种单机开发场景里,硬编码反而最不容易出错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










