根本原因是SameSite属性不匹配:现代浏览器默认SameSite=Lax,跨域请求需显式设SameSite=None且必须搭配secure=true(HTTPS环境),否则Cookie被静默丢弃。

PHP 跨域请求中 Session 丢失,光配 Access-Control-Allow-Credentials: true 不够——SameSite 属性不匹配才是生产环境静默失败的主因。
fetch 请求带 credentials 但 PHP $_SESSION 仍为空
这是最典型的“看着配置都对,但就是不生效”场景。前端用了 credentials: 'include',后端也返回了 Access-Control-Allow-Credentials: true 和明确的 Access-Control-Allow-Origin(不能是 *),但 $_SESSION 还是空的。
根本原因往往不在 CORS 头本身,而在 PHP 设置的会话 Cookie 的 SameSite 属性。现代浏览器(Chrome 80+、Firefox 79+、Safari 14+)默认将未显式声明 SameSite 的 Cookie 视为 SameSite=Lax,而 Lax 会阻止跨域 POST/PUT 等请求携带 Cookie。
实操建议:
使用 Playwright 为 jimeng.jianying.com 管理浏览器会话,导入 cookies/localStorage 以自动化视频生成工作流,支持图片上传等功能
立即学习“PHP免费学习笔记(深入)”;
- 在调用
session_start()前,用session_set_cookie_params()显式设置SameSite=None(注意拼写,不是None小写)且必须搭配secure=true - 确保你的站点走 HTTPS,否则
SameSite=None; Secure会被浏览器直接拒收 - 不要依赖
php.ini中的session.cookie_samesite—— 它在某些 PHP 版本(如 7.3 早期)不生效,代码层控制更可靠
示例:
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.yourdomain.com', // 注意开头的点,覆盖子域
'secure' => true, // 必须开启,否则 SameSite=None 无效
'httponly' => true,
'samesite' => 'None' // 字符串,首字母大写
]);
session_start();
phpEnv 下 session.cookie_samesite 配置失效
phpEnv 是 Windows 下的集成环境,其内置的 PHP 版本常为 7.3 或 7.4。这类版本对 php.ini 中 session.cookie_samesite 的支持不稳定:即使你写了 session.cookie_samesite = "None",实际 Set-Cookie 响应头里仍可能不出现 SameSite 字段,或被忽略。
原因在于:session.cookie_samesite 在 PHP 7.3.0 才引入,但早期补丁不完整;phpEnv 打包时可能未启用对应编译选项,或 ini 文件加载顺序导致被覆盖。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 不要只改
php.ini,务必在代码中用session_set_cookie_params()覆盖 - 用浏览器开发者工具 → Application → Cookies 查看实际下发的 Cookie,确认是否含
SameSite=None; Secure - 若 phpEnv 使用的是 Apache,检查
.htaccess是否有Header set Set-Cookie类覆盖行为
OPTIONS 预检请求后 session_start() 不创建新会话
跨域 POST/PUT 请求前,浏览器会发一次 OPTIONS 预检。如果后端对 OPTIONS 请求也执行了 session_start(),就可能意外生成一个无意义的新会话(因为预检请求不带凭证,无法关联原会话),后续真实请求反而拿不到有效 PHPSESSID。
这不是 bug,是误用。Session 启动应在业务逻辑路径上,而非所有请求入口无差别执行。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在 API 入口处判断请求方法:
if ($_SERVER['REQUEST_METHOD'] !== 'OPTIONS')再调用session_start() - 确保
OPTIONS响应头只包含 CORS 相关字段(Access-Control-Allow-Origin、Access-Control-Allow-Methods等),不包含Set-Cookie - 避免在全局中间件或公共 include 文件中无条件执行
session_start()
domain 参数不一致导致 Cookie 无法发送
前端域名是 app.example.com,后端 API 是 api.example.com,但 PHP 设置的 cookie_domain 是 example.com(缺了点)或 www.example.com(错域),都会导致浏览器拒绝发送 Cookie。
关键细节:
-
domain值必须以点开头(如'.example.com')才能被子域共享 - 若前端是
localhost,domain不能设为任何带点的值(浏览器会直接丢弃),开发时建议用条件判断绕过 - 生产环境部署到多级子域(如
admin.api.example.com)时,domain仍应设为'.example.com',而非'.api.example.com'
推荐写法:
$domain = $_SERVER['HTTP_HOST'];
if (strpos($domain, 'localhost') === false && strpos($domain, '127.0.0.1') === false) {
$cookieDomain = '.example.com';
} else {
$cookieDomain = '';
}
session_set_cookie_params([
'domain' => $cookieDomain,
'samesite' => 'None',
'secure' => !empty($cookieDomain), // localhost 不走 secure
'httponly' => true,
'path' => '/'
]);
session_start();
真正容易被忽略的,是 SameSite=None 和 Secure 的强绑定关系——哪怕只漏掉 secure=true,整个 Cookie 就会在 HTTPS 环境下被浏览器静默丢弃,连错误提示都没有。


















