本质是cookie作用域未对齐,需在session_start()前设ini_set('session.cookie_domain', '.example.com'),配access-control-allow-origin精确源、credentials: 'include'及共享session存储。

phpEnv 下跨域 Session 不一致,本质是 Cookie 作用域没对齐,不是 PHP 环境本身的问题,而是 session cookie 没被浏览器正确携带过去。
phpEnv 中 session.cookie_domain 必须显式设置
phpEnv 默认不设 session.cookie_domain,导致 PHP 生成的 session cookie 只绑定在当前完整域名(如 api.local)上。前端若在 localhost:8080 或 dev.example.com 发起请求,浏览器根本不会把该 cookie 自动带上——它压根“看不见”这个域匹配的 cookie。
解决方式是在 php.ini 或运行时强制指定:
- 修改 php.ini:
session.cookie_domain = ".example.com"(注意开头的点,表示包含所有子域) - 或在入口脚本顶部加:
ini_set('session.cookie_domain', '.example.com'); - 必须确保前后端共用同一根域名(如都走
example.com或其子域),否则.example.com对test.com无效
Access-Control-Allow-Origin 不能写 * 当启用 credentials
只要后端用了 header('Access-Control-Allow-Credentials: true');,Access-Control-Allow-Origin 就**绝对不能**是 *。否则浏览器直接拒绝响应,连 cookie 都不会发。
常见错误写法:header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Credentials: true'); → 这组头会直接让请求失败。
正确做法是动态反射 Origin:
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, ['http://localhost:8080', 'https://dev.example.com'])) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Credentials: true');
}
注意:Origin 是完整协议+域名+端口,http://localhost 和 http://localhost:8080 视为不同源。
前端 fetch / axios 必须开启 withCredentials
即使后端头全对,前端不主动声明要带 cookie,浏览器默认不发。这不是“自动行为”,而是明确的 opt-in 机制。
fetch 写法:fetch('/login', { credentials: 'include' })
axios 写法:axios.defaults.withCredentials = true; 或单次请求加 { withCredentials: true }
关键点:
-
credentials: 'include'是唯一能触发发送 cookie 的值('same-origin'不跨域,'omit'根本不发) - Vue/React 项目里,如果用全局配置,记得在创建实例前就设好,否则中间请求可能漏掉
- Postman、curl 默认不模拟 cookie 携带逻辑,所以本地测试正常 ≠ 前端联调正常
验证 cookie 是否真正生效的三个检查点
Session ID 不一致,问题往往卡在链路某一处。建议按顺序确认:
- 看响应头:登录接口返回的
Set-Cookie是否含Domain=.example.com和Path=/?没有就说明session.cookie_domain没生效 - 看请求头:验证码/登录请求的 Request Headers 里是否有
Cookie: PHPSESSID=xxx?没有说明前端没发,或浏览器因域不匹配过滤掉了 - 看服务端日志:两次请求的
session_id()输出是否相同?如果相同但$_SESSION为空,可能是 session_start() 前有输出、或 session.save_path 权限问题
最常被忽略的是:phpEnv 启动多个 PHP-FPM 实例时,若没共用 session 存储(比如默认文件路径不同),即使 cookie 正确,session 数据也读不到——这时得统一配 session.save_path 到共享目录或 Redis。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











