phpenv 自带 nginx 无法开箱即用支持跨域 cookie 传输和 session 共享,必须手动配置:统一 php 的 session.name、save_path 和 handler;在 nginx location 块中添加 proxy_cookie_domain、proxy_cookie_path、add_header access-control-allow-*(含 always)、ip_hash(防轮询丢失登录态),并确保 samesite=none+secure 与 https 环境匹配。

直接说结论:phpEnv 自带的 Nginx 无法开箱即用支持跨域 Cookie 传输,必须手动改配置;Session 共享也不能靠 phpEnv 自动完成,得统一 PHP 的 session 存储路径、name 和前缀,再配合 Nginx 的 proxy_cookie_domain 或 ip_hash 才能真正生效。
phpEnv 的 Nginx 默认不透传或修正 Cookie 头
phpEnv 封装的 Nginx 默认没配 add_header、proxy_cookie_domain 或 proxy_cookie_path,所以即使后端 PHP 返回了 Set-Cookie: sessionid=xxx; Domain=.local; Path=/; Secure; SameSite=None,Nginx 也不会帮你把 Domain 从 .local 改成 .test,也不会补上缺失的 Access-Control-Allow-Credentials: true。前端发 credentials: 'include' 请求后,浏览器收不到合法响应头,就直接丢弃 Cookie。
实操建议:
- 进 phpEnv 安装目录(比如
C:\phpEnv\nginx\conf\vhost\),找到对应站点的.conf文件 - 在
location /或location ~ \.php$块里加这几行(注意必须和proxy_pass在同一块):
proxy_cookie_domain ~\.?local$ .test; proxy_cookie_path / /; add_header 'Access-Control-Allow-Origin' 'https://fe.test' always; add_header 'Access-Control-Allow-Credentials' 'true' always;
⚠️ 注意:proxy_cookie_domain 的正则必须匹配你后端 Set-Cookie 里的原始 Domain;add_header 后面的 always 参数不能省,否则 301/302 跳转时头会丢失。
phpEnv 下 PHP 的 session 配置默认是隔离的
phpEnv 每个 PHP 版本(如 PHP 7.4、8.1)有独立的 php.ini,且默认 session.save_path 指向各自版本下的 tmp 目录,session.name 也可能是默认的 PHPSESSID,但不同版本之间不互通——这就导致你在 PHP 7.4 登录写入的 session,在 PHP 8.1 的 API 接口里读不到。
实操建议:
- 统一修改所有要用到的 PHP 版本的
php.ini(路径类似C:\phpEnv\php\php-7.4\php.ini) - 确保这三项完全一致:
session.name = PHPSESSID session.save_handler = files session.save_path = "C:/phpEnv/tmp/session"
如果用 Redis,就都设成 redis 并共用同一个 redis://127.0.0.1:6379;路径必须是**绝对路径**,且目录要有写权限。别用相对路径或 %TEMP% 这类变量,phpEnv 不一定识别。
跨域请求被轮询打散,登录态瞬间失效
phpEnv 默认 Nginx upstream 是轮询(round-robin),前端从 http://localhost:8080 访问登录页,后端 PHP 写了 session;但下个 API 请求被分到另一台 backend,它没这个 session 数据,就判定未登录。这不是 Cookie 没传,而是 session 根本不在那台机器上。
实操建议:
- 在
upstream块里启用ip_hash(仅限开发环境,生产慎用):
upstream php_backend {
ip_hash;
server 127.0.0.1:9000;
server 127.0.0.1:9001;
}
⚠️ 注意:ip_hash 不支持动态增减后端,改配置后要 nginx -s reload;如果你走公司代理或调试用 Charles/Fiddler,$remote_addr 会变成代理 IP,所有人挤一台后端,此时该换 hash $http_x_forwarded_for consistent; 并确保代理设置了 X-Forwarded-For。
Chrome 80+ 下 SameSite 默认行为会静默拦截 Cookie
哪怕 Nginx 和 PHP 都配对了,Chrome 80 之后默认把跨域 Cookie 当作 SameSite=Lax 处理,而 credentials: include 要求必须显式声明 SameSite=None; Secure。如果后端 PHP 没在 setcookie() 里加这两个参数,或者 Nginx 没用 proxy_cookie_flags 补上,浏览器就直接忽略这个 Cookie。
实操建议:
- PHP 侧必须这样设 Cookie:
setcookie('PHPSESSID', $value, [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.test',
'secure' => true,
'httponly' => true,
'samesite' => 'None'
]);
或者在 php.ini 里统一加:
session.cookie_samesite = "None" session.cookie_secure = 1
Nginx 侧可兜底补旗(需 1.19.3+):
proxy_cookie_flags ~ secure samesite=None;
最容易被忽略的是:本地开发用 http://localhost 时,Secure 属性会让 Chrome 拒绝存储 Cookie——必须用 HTTPS 或把域名改成 https://local.test 并配好本地证书,否则整个链路从第一步就断了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











