phpEnv中直接在server块用add_header不生效,因Nginx默认不向非2xx响应(如OPTIONS返回204)发送自定义头,需加always修饰符;且PHP-FPM子请求不继承父级add_header,必须在location块内配置并确保if($request_method='OPTIONS')置于fastcgi_pass前。

phpEnv 是一套面向 Windows 的 PHP 集成环境(类似 XAMPP),默认使用 Nginx + PHP-FPM 架构。它不自带全局 CORS 配置,必须手动在 Nginx 的 location 块中添加响应头,且需特别注意 PHP-FPM 场景下 OPTIONS 请求的拦截时机和头传递逻辑。
为什么直接在 server 块加 add_header 不生效
phpEnv 的 Nginx 配置通常将 PHP 脚本交由 location ~ \.php$ 处理,而 add_header 指令在子请求(如 FastCGI)中默认不继承——尤其当响应状态不是 2xx(比如 OPTIONS 返回 204)时,头会被丢弃。更关键的是:若未加 always 修饰符,Nginx 在 204、4xx 等非标准成功响应中根本不会发送自定义头。
- 错误写法:
add_header Access-Control-Allow-Origin "*";→ OPTIONS 返回 204 时该头完全不出现 - 正确写法:
add_header 'Access-Control-Allow-Origin' '*' always;→ 强制所有响应码都携带 - phpEnv 默认配置里往往没有
always,这是跨域失败最隐蔽的原因之一
在 phpEnv 的 nginx.conf 中配置 location 级 CORS
打开 phpEnv 安装目录下的 nginx/conf/nginx.conf,找到对应 PHP 的 location ~ \.php$ 块(或你自定义的 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;
}
<p>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-Expose-Headers' 'Content-Length,Content-Range' always;</p>⚠️ 注意顺序:if ($request_method = 'OPTIONS') 必须放在 fastcgi_pass 或 proxy_pass 之前,否则预检请求仍会转发给 PHP-FPM,导致 405 或空白响应。
立即学习“PHP免费学习笔记(深入)”;
带 Cookie 或 Authorization 时必须改用动态 Origin
若前端设置了 credentials: 'include'(例如登录态 Cookie 或 Bearer Token),则 Access-Control-Allow-Origin: * 会被浏览器直接拒绝。此时不能硬编码,需用变量匹配可信源:
- 在
server块顶部加:set $cors_origin ""; - 再加 if 判断:
if ($http_origin ~* "^https?://(localhost:8080|127\.0\.0\.1:3000)$") { set $cors_origin $http_origin; } - 后续所有
add_header 'Access-Control-Allow-Origin' "$cors_origin" always;和add_header 'Access-Control-Allow-Credentials' 'true' always; - 务必同步开启
Access-Control-Allow-Credentials: true,且仅当$cors_origin非空时才输出该头
phpEnv 是开发环境,但 CORS 配置一旦写错,前端控制台只会报 “No 'Access-Control-Allow-Origin' header”,不会告诉你缺了 always、漏了 OPTIONS 拦截、或 Access-Control-Allow-Credentials 和通配符冲突——这些细节全靠手动核对 Nginx 日志和响应头原始值来验证。



















