本文目录导读:

在 PHP 中,分区 Cookie(Partitioned Cookie) 是一种通过 Partitioned 属性实现的 Cookie 隔离机制。
这是为了解决第三方 Cookie 被浏览器逐步禁用后,跨站资源(如嵌入的 iframe)无法保持登录状态的问题。
什么是分区 Cookie?
- 传统 Cookie:按域名存储,一个网站总能读取自己域名的 Cookie。
- 分区 Cookie:在传统域名基础上,额外加上顶级站点(Top-Level Site)作为存储分区。
- 浏览器为每个顶级站点维护一个独立的 Cookie 存储槽。
简单说:
example.com的 Cookie 在a.com和b.com下是彼此隔离的,即使它们都访问example.com的资源。
PHP 中设置分区 Cookie
PHP 的 setcookie() 函数从 PHP 7.3 开始支持 samesite 数组参数,但 Partitioned 属性是较新的功能,需要:
- PHP 7.3+(需要手动拼装)
- PHP 8.x(原生支持)
使用 setcookie() 的 options 数组(推荐)
<?php
// 传统方式(PHP 7.3+)
setcookie('session_id', 'abc123', [
'expires' => time() + 3600,
'path' => '/',
'domain' => 'example.com', // 你的域名
'secure' => true, // 必须 HTTPS
'httponly' => true,
'samesite' => 'None', // 必须为 None
'partitioned' => true // 📌 启用分区
]);
?>
注意:PHP 8.0 的
setcookie()还没有partitioned参数,需要通过 Header 方式手动设置。
手动设置 Header(兼容所有 PHP 版本)
<?php
$cookieName = 'session_id';
$cookieValue = 'abc123';
$expires = time() + 3600;
$path = '/';
$domain = 'example.com';
$secure = true;
$httponly = true;
// 拼接完整 Cookie 字符串
$header = sprintf(
'%s=%s; Expires=%s; Path=%s; Domain=%s; Secure; HttpOnly; SameSite=None; Partitioned',
$cookieName,
urlencode($cookieValue),
gmdate('D, d M Y H:i:s T', $expires),
$path,
$domain
);
header("Set-Cookie: $header", false);
?>
使用 PHP 8.2+ 原生支持
<?php
// PHP 8.2+ 直接支持 partitioned 参数
setcookie(
'session_id',
'abc123',
[
'expires' => time() + 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None',
'partitioned' => true
]
);
?>
验证 Cookie 是否正确设置
在浏览器开发者工具(F12)→ Application → Cookies 中查看:
Name: session_id
Value: abc123
Domain: example.com
Path: /
Expires: ...
Secure: ✅
HttpOnly: ✅
SameSite: None
Partitioned: ✅ ← 必须有这个标记
读取分区 Cookie
读取方式与普通 Cookie 完全一样,PHP 会自动处理分区逻辑:
<?php
if (isset($_COOKIE['session_id'])) {
echo "Session ID: " . $_COOKIE['session_id'];
} else {
echo "未找到 Cookie";
}
?>
删除分区 Cookie
<?php
// 设置过期时间为过去的时间即可
setcookie('session_id', '', [
'expires' => time() - 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None',
'partitioned' => true
]);
?>
使用场景
| 场景 | 是否适合使用 Partitioned |
|---|---|
| 普通网站内部登录状态 | ❌ 不需要 |
| 嵌入 iframe 的第三方服务(支付、聊天、地图) | ✅ 需要 |
| 跨站图片/资源加载 | ✅ 可能需要 |
| 跨域 JS 调用 API | ❌ 不适用(需 CORS) |
注意事项与坑
| 问题 | 说明 |
|---|---|
| 必须 HTTPS | Partitioned 要求 Secure 属性,必须使用 HTTPS |
| SameSite=None 必须一起设置 | Partitioned 必须与 SameSite=None 配合使用 |
| 浏览器兼容性 | Chrome 115+、Edge 115+、Firefox 126+ 支持;Safari 部分支持 |
| 移动端限制 | Android WebView 较旧版本不支持 |
| 调试困难 | 分区 Cookie 在不同站点下是隔离的,调试时需要切换场景 |
完整示例(实际使用)
<?php
// 设置分区 Cookie
function setPartitionedCookie($name, $value, $expires = 3600) {
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
$cookieOptions = [
'expires' => time() + $expires,
'path' => '/',
'secure' => $secure,
'httponly' => true,
'samesite' => 'None',
// PHP 8.2+ 支持;旧版本用手动方式
'partitioned' => true
];
setcookie($name, $value, $cookieOptions);
}
// 使用
setPartitionedCookie('user_token', 'abc123', 86400);
// 读取
if (isset($_COOKIE['user_token'])) {
$token = $_COOKIE['user_token'];
// 验证 token...
}
?>
| 方法 | PHP 版本 | 推荐度 |
|---|---|---|
setcookie() + options |
PHP 8.2+ | ⭐⭐⭐ 最简洁 |
| 手动 Header 拼接 | PHP 7.3+ | ⭐⭐⭐ 兼容性最好 |
| Header 手动方式 | 任意版本 | ⭐⭐ 老项目可选 |
最重要的一点:Partitioned 必须搭配 Secure + SameSite=None,否则浏览器会忽略该属性,同时要确保你的服务器支持 HTTPS。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播