为什么关掉浏览器就要重新登录?Cookie 4KB 上限 12 组实测
单个 Cookie 的 name+value 上限是 4096 字节,value 最多只能写 4082 字节。
同一域名连续写 240 个 Cookie,浏览器最后只留下 180 个。
关掉浏览器要重新登录,多半不是你点错了,是会话 Cookie 被清掉了。

一、先看结论:4KB 不是玄学,是 4096 字节的硬边界
我把实验室跑在一台 Windows 机器的 Chrome 156 上。
测试页面是 http://127.0.0.1:8765,不是 file://。
Cookie 在 file:// 下不可用,这一点先记住。
| 项目 | 实测值 | 说明 |
|---|---|---|
| 单个 Cookie 的 name+value 上限 | 4096 B | value 最大 4082 B,含等号合计 4097 B |
| 同域 Cookie 数量 | 180 个 | 连续写 240 个,最后保留 180 个 |
| Max-Age=2 的过期时间 | 3102 ms | 3 秒后读回为空 |
| 中文值的编码长度 | 5 字符变 45 字符 | 每个中文字符编码成 9 个可见字符 |
| 6000 B 超大 Cookie | 赋值不抛异常,读回 0 B | 浏览器静默拒绝 |
4096 不是 4000,也不是 4KB 的近似值。
浏览器按字节算,不按字符算。
二、为什么值得看:登录态掉线多半是 Cookie 生命周期问题
登录态通常是一枚 session id,放在 Cookie 里。
服务端认得这枚 id,才把你当成已登录用户。
会话 Cookie 没有 Max-Age 或 Expires。
浏览器进程退出时,它会被清掉。
持久 Cookie 带了过期时间,关掉浏览器还会留着。
很多网站把「记住我」做成持久 Cookie,把普通登录做成会话 Cookie。
所以同一个网站,勾不勾「记住我」,行为可能完全不同。
这不是前端故意坑你,是 Cookie 生命周期在起作用。
另一个常见坑是容量。
Cookie 只有 4KB 左右的空间,还要和同域其他 Cookie 抢。
写超了不会报错,读回才发现没写进去。
三、准备环境:进入码道 Web
浏览器打开码道 Web 版: https://devcloud.cn-north-4.huaweicloud.com/chat?source=dmzntgwlb&sourcead=dmzntgwlb1&invitecode=INV-IXhxk5bwWx_qKSP1FcgSuiOEf6ruDXtjvLFiCH9nMs5dZGLapaSSylwt-cKRj5LoT3MlxikWxy8VhqplfvtQjefQOq31Tbp3R3wYP3K535Cn4XTaUzqqExKPYTWvvw4LijV14IS1torXdTGp7oyXb6SR5VxgYTg50jM ,登录后就能在对话窗口输入需求,不需要装软件。
码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。
四、怎么做的:把 Cookie 的边界搬到页面上
我给它的需求很具体:单文件、深色界面、真实 document.cookie、12 组断言、容量扫描和失败路径。
它先生成了页面骨架,再把每个测试做成可单独点击的卡片。
我没有让它写死结果。
所有 PASS/FAIL 都来自当前页面的读写。
容量扫描用二分查找,范围 1000 到 5000 字节。
每次写入后立刻读回,读回值完全一致才算成功。
数量上限用 lab_count_ 前缀写 240 个短 Cookie。
每写 8 个刷新一次进度,最后统计前缀还剩下多少。
12 组断言覆盖会话、持久、覆盖、过期、中文、分号、空格、SameSite 和 4096 边界。
页面底部有 12/12 的实时计数。
五、验证与踩坑:12 组断言和两次扫描
我先跑容量扫描,结果是 value 4082B。
name 是 lab_size_probe,长度 14 字节。
14 + 1 + 4082 = 4097,正好卡在 4096 的边界外一条。
换句话说,name+value 合计 4096B 能写,4097B 就被拒绝。

这也解释了一个容易忽略的点:Cookie 名字越长,value 能用的空间越少。
如果你把用户名、时间戳都塞进 Cookie 名,等于自己吃掉容量。
数量扫描写了 240 个,最后保留 180 个。
同域当时只有这 180 个实验 Cookie,没有其他 Cookie 干扰。
这个 180 是当前 Chrome 的结果,不保证所有浏览器都一样。

12 组断言跑了 12/12。
T04 真的等了 3102ms,确认 Max-Age=2 的 Cookie 在 3 秒后读回为空。
T05 把 5 个中文字符写成 Cookie,读回是 45 个字符。
每个中文字符被编码成 9 个可见字符,长度翻 9 倍。
T06 写 abc;def,读回只有 abc。
分号是 Cookie 属性的分隔符,值里不能原样保留。
T10 在 HTTP 页面写 SameSite=None,读回为空。
Chrome 要求 SameSite=None 必须同时带 Secure。

失败路径单独做了一张卡。
写 6000B 的 value,document.cookie 没有抛异常。
读回长度是 0B。
页面给出的提示是:写入被浏览器静默拒绝。
这段是我这次最想保留的证据。
前端很难通过赋值语句判断 Cookie 是否真的写成功。
唯一可靠的办法是写完后读回比对。

六、本地复现:一条 http.server 命令
仓库地址:https://atomgit.com/deli007/demo_park/tree/main/codearts-cookie-session-lab
这个仓库没有单独放 LICENSE 文件,代码按学习交流使用。
git clone https://atomgit.com/deli007/demo_park.git
cd demo_park/codearts-cookie-session-lab
python -m http.server 8765
浏览器打开 http://127.0.0.1:8765/。
不要直接双击 index.html。
file:// 下 document.cookie 不工作,页面会提示你先起一个 HTTP 服务。
页面没有外部依赖,断网也能跑。
我用 Chrome 156 复跑了一次,容量、数量、12 组断言和失败路径都能重现。
七、使用码道体会
需求里写验收方式,比写「做个 Cookie 实验室」有用得多。
我把 12 组断言、4096 边界、失败路径都写进需求,生成结果就接近可验收状态。
让页面自己跑测试,比让 AI 口头说「已完成」可靠。
这次没有让它编造数据,所有数字都来自页面真实读写。
单文件应用适合这种小实验,复制、部署、复跑都简单。
但单文件也有边界:代码长了以后,维护成本会上升。
八、结果与下一步
现在这个页面能做四件事:看当前 Cookie、扫容量、扫数量、跑 12 组断言。
它也能模拟关闭浏览器,让你直观看到会话 Cookie 消失、持久 Cookie 留下。
下一步我想补两个场景。
一个是 Path 和 Domain 的作用域,另一个是跨站请求时 SameSite 的真实表现。
这两个都需要多路径或多站点环境,单页实验室做不完全。
这次先把单域内的边界测清楚。
如果你也遇到过「昨天还好好的,今天就要重新登录」,可以先看 Cookie 的过期时间。
再看它是不是会话 Cookie。
最后再看同域 Cookie 是不是写满了。
这三步比反复清缓存更有针对性。
浙公网安备 33010602011771号