如果你已经搞定了 PHP 的 CORS,
但 Session 一到跨域就“像没生效一样” ,那你并不孤单。
典型表现只有一句话:
接口能调通,但 Session 每次都是新的。
然后你会开始搜:
- php session 跨域
- php session 跨域失效
- php 跨域请求解决方案
- php cors 跨域
这篇文章,我不讲概念,
只按真实项目的排查顺序,告诉你 Session 到底是怎么丢的。
一、Session 跨域失败,本质是 Cookie 没带上
PHP Session 能不能用,完全取决于浏览器有没有带 Cookie。
浏览器不带 Cookie,
PHP 不管你代码写得多完美,Session 都一定失效。
二、排查顺序一定要对(重点)
下面这 5 个原因,
按顺序查,别乱试。
原因一:Access-Control-Allow-Origin 用了 *
这是最致命、也是最常见的错误。
❌ 错误写法:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
浏览器会直接拒绝携带 Cookie。
✅ 正确写法:
header("Access-Control-Allow-Origin: https://www.example.com");
header("Access-Control-Allow-Credentials: true");
👉 Session 跨域,Origin 必须写死
原因二:前端没开启 credentials(很多人忽略)
就算后端全写对了,
前端不配合,一样白搭。
fetch 示例:
fetch(url, {
credentials: 'include'
});
axios 示例:
axios.get(url, {
withCredentials: true
});
👉 这一步不写,Cookie 根本不会发。
原因三:Cookie 的 SameSite 属性不对(高频翻车)
现在浏览器默认是:
SameSite=Lax
跨站请求 不会带 Cookie。
你必须明确设置:
session_set_cookie_params([
'samesite' => 'None',
'secure' => true
]);
⚠️ 两个隐藏条件:
SameSite=None必须 HTTPS- HTTP 环境直接失效
原因四:Cookie 域名不一致
这是很多人看不见、却真实存在的坑。
常见错误场景:
- 前端:
www.example.com - 接口:
api.example.com - Cookie 域:默认只绑当前子域
👉 结果:Session 看起来“丢了”。
正确做法:
ini_set('session.cookie_domain', '.example.com');
让 Cookie 在整个主域下生效。
原因五:OPTIONS 预检请求没处理
只要你:
- 跨域
- 带 Cookie
- 用 POST / 自定义 Header
浏览器一定会先发 OPTIONS 请求。
如果 PHP 没处理:
👉 后续真正的请求根本不会到达。
三、一个完整可跑的 Session 跨域示例
这是一个真实项目可用级别的最小示例。
<?php
$origin = 'https://www.example.com';
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
exit;
}
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None'
]);
session_start();
$_SESSION['uid'] = 10086;
echo json_encode([
'session_id' => session_id(),
'uid' => $_SESSION['uid']
]);
四、phpstudy 环境下,Session 跨域为什么更容易失败?
原因很现实:
1️⃣ 本地没 HTTPS
2️⃣ 用 localhost / 127.0.0.1
3️⃣ Cookie SameSite 直接被浏览器拦
👉 phpstudy 只能验证逻辑,不能完全验证跨域 Cookie
五、什么时候不建议用 Session 跨域?
说句实话:
- 多域名
- 多端(H5 / 小程序 / App)
- 前后端完全分离
👉 Token / JWT 更省心
Session 跨域是可以做,
但维护成本很高。
六、为什么我强烈建议用“排查顺序”?
因为 Session 跨域:
- 不是一个点
- 是一串条件叠加
- 错一个,全盘失效
按顺序查,比瞎试效率高 10 倍。
PHP Session 跨域失效,
不是 Session 的问题,是 Cookie 的问题。
只要 Cookie 没进浏览器,
Session 一定是“假的”。