浏览器会在每次请求时自动将 Cookie 发送到服务器,这是由 HTTP 协议 和 Cookie 的工作机制 决定的。
1. 为什么浏览器会在每次请求时自动发送 Cookie?
(1)HTTP 协议的设计
- HTTP 是一种无状态协议,这意味着服务器无法记住用户的请求。
- 为了让服务器能够识别用户并保持状态,引入了 Cookie 机制。
- 当服务器设置了一个 Cookie 后,浏览器会按照 HTTP 协议的规则,在后续请求中自动将该 Cookie 发送回服务器。
(2)Cookie 的工作机制
- 服务器设置 Cookie:
- 服务器通过 HTTP 响应头中的 Set-Cookie 字段向浏览器发送一个 Cookie。
- 示例:HTTP/1.1 200 OK
Set-Cookie: PHPSESSID=abc123; path=/; HttpOnly
- 浏览器存储 Cookie:
- 浏览器会根据 Set-Cookie 的内容,将 Cookie 存储在本地。
- Cookie 的属性(如域名、路径、有效期等)决定了它在哪些请求中会被发送。
- 浏览器发送 Cookie:
- 在后续请求中,浏览器会根据请求的 URL 和 Cookie 的属性,自动将匹配的 Cookie 添加到 HTTP 请求头中的 Cookie 字段。
- 示例:GET /page.php HTTP/1.1
Host: example.com
Cookie: PHPSESSID=abc123
(3)通俗解释
- 想象你去一家咖啡店,店员给你一张会员卡(Cookie),并告诉你每次来的时候带上这张卡。
- 下次你再去这家咖啡店时,你会自动带上会员卡(浏览器发送 Cookie)。
- 店员看到会员卡后,就知道你是谁,并提供相应的服务。
2. PHP 底层到底做了什么事情?
(1)设置 Cookie
- 当调用 session_start() 时,PHP 会自动设置一个名为 PHPSESSID 的 Cookie,用于存储会话 ID。
- 如果需要手动设置其他 Cookie,可以使用 setcookie() 函数。
- 示例:setcookie('username', 'Alice', time() + 3600, '/', '', true, true);
- 参数说明:
- 'username':Cookie 名称。
- 'Alice':Cookie 值。
- time() + 3600:有效期为 1 小时。
- '/':作用路径为整个域名。
- '':域名为空,表示当前域名。
- true:仅通过 HTTPS 传输(Secure 标志)。
- true:禁止 JavaScript 访问(HttpOnly 标志)。
- 参数说明:
(2)读取 Cookie
- PHP 会自动解析 HTTP 请求头中的 Cookie 字段,并将其存储在 $_COOKIE 超全局数组中。
- 示例:if (isset($_COOKIE['PHPSESSID'])) {
echo "会话 ID:" . $_COOKIE['PHPSESSID'];
}
(3)管理会话
- 当浏览器发送 PHPSESSID Cookie 时,PHP 会根据其值找到对应的会话数据。
- 如果没有找到有效的会话 ID,PHP 会生成一个新的会话 ID,并设置新的 PHPSESSID Cookie。
3. 完整代码示例 + 详细注释
以下是一个完整的 PHP 示例,展示如何设置和读取 Cookie,以及如何使用 Cookie 管理会话。
<?php
// 启动会话
session_start(); // 开始一个新的会话,或者恢复现有的会话
// 输出当前会话 ID
echo "当前会话 ID:" . session_id() . "\\n";
// 检查是否通过 Cookie 传递会话 ID
if (isset($_COOKIE['PHPSESSID'])) {
echo "会话 ID 通过 Cookie 传递。\\n";
} else {
echo "会话 ID 未通过 Cookie 传递。\\n";
}
// 手动设置一个自定义 Cookie
setcookie('username', 'Alice', time() + 3600, '/', '', true, true);
echo "已设置 Cookie:username=Alice\\n";
// 查看当前的 Cookie
print_r($_COOKIE);
// 删除自定义 Cookie
setcookie('username', '', time() – 3600, '/');
echo "已删除 Cookie:username\\n";
4. 每一行代码的详细注释
<?php
// 启动会话
session_start();
// 这行代码告诉 PHP 开始一个新的会话,或者恢复之前保存的会话。
// 输出当前会话 ID
echo "当前会话 ID:" . session_id() . "\\n";
// session_id() 返回当前会话的唯一标识符(ID)。
// 检查是否通过 Cookie 传递会话 ID
if (isset($_COOKIE['PHPSESSID'])) {
echo "会话 ID 通过 Cookie 传递。\\n";
// 如果 $_COOKIE 中存在 PHPSESSID,说明会话 ID 是通过 Cookie 传递的。
} else {
echo "会话 ID 未通过 Cookie 传递。\\n";
// 如果 $_COOKIE 中不存在 PHPSESSID,说明会话 ID 不是通过 Cookie 传递的。
}
// 手动设置一个自定义 Cookie
setcookie('username', 'Alice', time() + 3600, '/', '', true, true);
// setcookie() 设置一个名为 username 的 Cookie,值为 Alice。
// 参数说明:
// – 'username':Cookie 名称。
// – 'Alice':Cookie 值。
// – time() + 3600:有效期为 1 小时。
// – '/':作用路径为整个域名。
// – '':域名为空,表示当前域名。
// – true:仅通过 HTTPS 传输(Secure 标志)。
// – true:禁止 JavaScript 访问(HttpOnly 标志)。
echo "已设置 Cookie:username=Alice\\n";
// 提示用户 Cookie 已设置。
// 查看当前的 Cookie
print_r($_COOKIE);
// 输出当前所有的 Cookie,包括 PHPSESSID 和 username。
// 删除自定义 Cookie
setcookie('username', '', time() – 3600, '/');
// 通过设置过期时间为过去的时间(time() – 3600),删除名为 username 的 Cookie。
echo "已删除 Cookie:username\\n";
// 提示用户 Cookie 已删除。
5. 总结
- 为什么浏览器会自动发送 Cookie?
- HTTP 协议规定,浏览器会根据 Cookie 的属性,在每次请求中自动将匹配的 Cookie 发送到服务器。
- PHP 底层做了什么?
- 设置和解析 Cookie。
- 使用 PHPSESSID Cookie 管理会话。
- 如何优化 Cookie 的使用?
- 设置 Secure 和 HttpOnly 标志,增强安全性。
- 定期清理无效或过期的 Cookie。
评论前必须登录!
注册