🕸️ 第二章 Web特有的架构
📄 一句话概括

HTTP 是无状态的,Cookie 就是补上去的那层记性——它让浏览器每次自己带上一小段信息,服务器这才认得出你。

📝 本节和前面几节的关系

2-6 讲过 HTTP 无状态这个设计,2-12 讲完服务器端。从这一条起连着两条讲【怎么把无状态变成有记性】:这一条讲 Cookie(怎么把凭证带来带去),下一条讲会话(凭证能开哪个柜子)。

一、从无状态到有记性

一次典型的来回是四步:

第一步,你登录,服务器在响应里写一行 Set-Cookie,里面是一小段随机字符串。第二步,浏览器把它存下来,并按规则绑定到某个域名上。第三步,之后每次请求同一个域名,浏览器自动在请求头里带上它。第四步,服务器凭这一小段认出你。

这里有个关键点:是浏览器自动带的。你不需要每次手动填——这既是它好用的地方,也是它危险的来源:跨站触发的请求,也会自动带上你的 Cookie。这正是下一节要讲的跨站伪造。

二、几个属性决定它怎么活

Cookie 不是一个单纯的字符串,它带一串属性,决定它能发给谁、活多久、脚本能不能读。

其中三个和安全直接相关:Secure 只走加密连接、HttpOnly 让脚本读不到、SameSite 挡住跨站自动携带。三个都不写,等于把钥匙放在门垫下面——2-10 提醒过一次,这里就是它的具体形式。

三、动手 Demo:量一量 Cookie 的账

sid, jwt = 100, 850
print("会话 Cookie 每次约 %d 字节,令牌约 %d 字节" % (sid, jwt))
for n in (1000, 100000):
    print("%7d 次请求:%7.2f MB  vs  %7.2f MB"
          % (n, sid * n / 1048576.0, jwt * n / 1048576.0))

实跑输出:

--------------------------------------------------------------------
D13  支持重新连接的机制:Cookie
--------------------------------------------------------------------
  D6 说过 HTTP 是无状态的:服务器记不住你。
  Cookie 就是为了补这个缺口——让浏览器每次自己带上一小段信息。

  一次典型的来回是这样:
    1. 你登录,服务器在响应里写一行 Set-Cookie: sid=8f3a...
    2. 浏览器把它存下来,并按规则绑到某个域名上
    3. 之后每次请求同一个域名,浏览器自动带上 Cookie: sid=8f3a...
    4. 服务器凭这一小段认出你

  一个 Cookie 活成什么样,由这几个属性决定:
  ----------------------------------------------------------------------------------------
  属性                管什么                  不写会怎样
  ----------------------------------------------------------------------------------------
  Domain              能发给哪些域名          默认只发给设置它的那个域名
  Path                这个域名下哪些路径      默认只有同目录及子目录
  Expires / Max-Age   什么时候过期            不写就是会话 Cookie,关浏览器就没
  Secure              只走加密连接            明文也能发,容易被中途截走
  HttpOnly            脚本读不到              前端脚本能读它,跨站脚本能偷走
  SameSite            跨站请求带不带          默认 Lax,能挡住大部分跨站伪造
  ----------------------------------------------------------------------------------------

  它有多大?几个上限数字:
  ----------------------------------------------------------------------------------------
  项目                              上限
  ----------------------------------------------------------------------------------------
  单条 Cookie 的大小                约 4 KB
  一个域名下的条数                  各家不同,Chrome 约 180 条
  一次请求头的总大小                服务器通常卡在 8 KB 左右
  ----------------------------------------------------------------------------------------
  注意最后一行:它不是【建议】,是硬限制——
  所以不能把数据一股脑塞进 Cookie,真正的数据要放在服务器那边的会话里。

  ⚠️ 2026 现状:这一条里变化最大的是【第三方 Cookie】。
  教材写作时,整个行业都在等 Chrome 把它关掉。四年之后,事情拐了个弯:
  ----------------------------------------------------------------------------------------
  时间          发生了什么
  ----------------------------------------------------------------------------------------
  2024-01-04    Chrome 对 1% 的用户默认限制第三方 Cookie(一次大型测试)
  2024-07-22    谷歌宣布不再一刀切淘汰第三方 Cookie
  2025-04-22    连【让用户自己选】的独立提示框也放弃了
  2025-10-17    宣布退役大部分隐私沙盒技术(理由:实际使用率太低)
  2026 年当下   Chrome 里第三方 Cookie 仍默认可用,由用户自己在设置里管
  ----------------------------------------------------------------------------------------

  被砍掉的是 Topics、Protected Audience、归因报告、共享存储、相关网站集这些;
  留下来的只有三个,都是【有明确用途、不带跨站追踪】的:
  ----------------------------------------------------------------------------------------
  留下来的              干什么
  ----------------------------------------------------------------------------------------
  CHIPS                 分区 Cookie:嵌在别人页面里的服务也有柜子,但跨不了站
  FedCM                 浏览器原生的登录接口,替代【用某账号登录】那套第三方脚本
  Private State Tokens  反欺诈信号,不靠追踪你是谁
  ----------------------------------------------------------------------------------------

  这件事落到你身上有两个实际影响:
    1. 无痕模式仍然默认拦住第三方 Cookie——所以任何依赖它的功能,
       都要能在【被拦住】的情况下正常工作。
    2. 【Cookie 要没了】这句判断,在 2026 年不成立;
       但【Cookie 越来越不可靠】这句是成立的:
       用户会关、浏览器会分区、法规要求先拿到同意。

读这个输出:小批量的差别可以忽略,量一大就藏不住了。十万次请求下,一个是几兆,一个是几十兆——注意这只是【多带的那点字节】,还没算服务器为了记住你而付出的开销。所以 Cookie 里应该只放钥匙,不放家具。

四、上限:为什么不能把数据塞进 Cookie

Cookie 有几条硬上限:单条约 4 KB、一个域名下条数有限、一次请求能带的头部总大小也有天花板(服务器这一侧通常卡在 8 KB 左右)。

最后一条尤其要注意:它不是建议,是硬限制。超过就会被截断或直接拒绝——所以真正的数据要放在服务器那边的会话里(下一节),Cookie 只负责把钥匙带过去。

五、⚠️ 2026 现状

这一条里变化最大的是第三方 Cookie。教材写作时整个行业都在等浏览器把它彻底关掉,四年之后事情拐了个弯:先是限制一小部分用户,不久宣布不再一刀切淘汰,接着连【让用户自己选】的独立提示框也放弃了,最后把大部分替代方案(隐私沙盒那一套)也退役了,理由是实际使用率太低。

留下来的只有三个,都带明确用途、不带跨站追踪:分区 Cookie(嵌在别人页面里的服务也有自己的柜子,但跨不了站)、浏览器原生的登录接口、以及不依赖追踪身份的反欺诈信号。

落到你身上有两个实际影响:无痕模式仍然默认拦住第三方 Cookie,所以依赖它的功能必须能在被拦住的情况下工作;另外,【Cookie 要没了】这句话在 2026 年不成立,但【Cookie 越来越不可靠】是成立的——用户会关、浏览器会分区、法规要求先拿到同意。

30 秒实验

  1. 按 F12,切到 Application 面板,在左边找到 Cookies。
  2. 看看一个你常用的网站存了多少条,随便挑一条点开看它的属性:HttpOnly 勾了吗?Secure 勾了吗?
  3. 试着删掉其中一条,刷新页面——很多网站会立刻把你变成未登录状态。

常见误区

  1. 错误:Cookie 是网站用来跟踪我的东西。——纠正:它本身只是个存取机制,用途由网站决定。让你保持登录、记住购物车、存语言偏好,靠的都是它。问题从来不在这个机制,在于谁用它、用来干什么。
  2. 错误:只要有 Cookie,服务器就能认出我。——纠正:认出你的是 Cookie 里的那串 ID 对应的记录,不只是一个字符串。Cookie 是钥匙,柜子在服务器那边——所以服务器把记录删掉,你手里有钥匙也没用(这就是退出登录的原理)。
  3. 错误:把用户信息直接放在 Cookie 里最省事。——纠正:Cookie 在用户手里,能看到、也能改。放进去的东西等于公开——所以正确的做法是里面只放一个随机 ID,真正的数据放服务器。
  4. 错误:第三方 Cookie 被淘汰了,Cookie 就没用了。——纠正:被讨论淘汰的是【跨站】那一类,而第一方 Cookie(你自己访问的这个网站设的)一直是主力,也是登录状态的主要载体。这两件事经常被混在一起说,看新闻时要分清。
自测三问(点开对答案) 1. Cookie 和会话是什么关系? —— **Cookie 是【怎么把钥匙带来带去】,会话是【这把钥匙能开哪个柜子】。**两者配合才完成【记住你】这件事:Cookie 负责传输,会话负责存储。**这也是为什么教材把它们放在相邻的两条里。** 2. 为什么 Cookie 里只应该放一个随机 ID? —— 因为**它在用户手里,用户能看到、也能改**。放什么进去就等于公开什么,改了什么就等于伪造什么。**所以正确做法是:Cookie 放一个没有含义的随机 ID,真正的信息留在服务器**——钥匙上什么都不写,丢了也能立刻作废。 3. 第三方 Cookie 这几年到底发生了什么? —— **拐了个弯**:从打算一刀切淘汰,到放弃淘汰,再到放弃【让用户自己选】,最后连大部分替代方案也退役了。所以 2026 年的现状是**在浏览器里仍默认可用、由用户自己决定**。**这件事真正的启示是:技术路线会被商业和监管反复改向,设计时不能押注它一定按计划走。**

相关笔记