Cookie、localStorage 和 sessionStorage 有什么区别?
简化版
Cookie 会随符合条件的 HTTP 请求自动发送,常用于登录态;localStorage 持久保存,除非手动清除;sessionStorage 只在当前标签页会话内有效。三者容量、生命周期、是否自动随请求发送、安全属性都不同。
详细版
Cookie:
- 容量较小。
- 可设置过期时间。
- 可通过
HttpOnly、Secure、SameSite增强安全。 - 会随请求自动发送,适合服务端会话。
localStorage:
- 容量较大。
- 持久保存。
- 不会自动随请求发送。
- 容易被 XSS 脚本读取。
sessionStorage:
- 生命周期限于当前标签页。
- 标签页关闭后清除。
- 同样不会自动随请求发送。
选择时要结合安全需求和数据生命周期。
完整版教学
一、Cookie 的特点
Cookie 最初就是为 HTTP 状态管理设计的。浏览器请求匹配域名和路径时,会自动带上 Cookie。
它适合保存会话标识,但也因为会自动发送,可能受到 CSRF 攻击影响。常用安全属性包括:
HttpOnly:禁止 JS 读取,降低 XSS 窃取风险。Secure:只在 HTTPS 下发送。SameSite:限制跨站请求携带 Cookie。
Cookie 容量较小,不适合存大数据。
二、localStorage 和 sessionStorage
localStorage 和 sessionStorage 属于 Web Storage。它们只在浏览器本地存储,不会自动加到请求头中。
localStorage 持久存在,适合保存主题、语言、非敏感偏好。sessionStorage 随标签页会话结束而清除,适合保存临时表单状态、一次性流程数据。
但它们都能被同源 JS 读取。如果页面存在 XSS 漏洞,攻击脚本也能读取其中内容。
三、登录态应该放哪里
这不是绝对问题。常见选择有两种:
- Cookie + HttpOnly:前端不能直接读取 token,安全性更好,但要处理 CSRF。
- Authorization Header + token:前端控制更灵活,但 token 如果存在 localStorage,容易被 XSS 窃取。
安全项目通常更倾向 HttpOnly Cookie,并配合 SameSite、CSRF Token、服务端校验。
四、面试追问与工程落地
面试官可能问:“localStorage 能不能跨标签页共享?”
同源下可以跨标签页共享,并且一个标签页修改 localStorage,其他标签页可以通过 storage 事件感知变化。sessionStorage 通常不在不同标签页共享。
工程中不要把敏感个人信息、长期有效 token、支付相关数据随意放 localStorage。存储只是方便,不是安全边界。
五、作用域、容量与同步成本
Cookie 的发送范围由 host/Domain、Path、Secure、SameSite 等属性共同决定,不是“同源存储”这么简单;Web Storage 则按 origin 隔离。Cookie 常见单条约 4KB,localStorage/sessionStorage 的配额通常是 MB 级但由浏览器策略决定,不能把某个固定值当跨浏览器保证。
| 维度 | Cookie | localStorage | sessionStorage |
|---|---|---|---|
| 自动随请求发送 | 匹配条件时发送 | 否 | 否 |
| 生命周期 | 会话或显式过期 | 持久到清理/淘汰 | 当前顶层浏览上下文会话 |
| JS 可读 | 非 HttpOnly 时 | 可以 | 可以 |
| API 特性 | 请求头/document.cookie | 同步 Web Storage | 同步 Web Storage |
| 典型容量 | KB 级 | MB 级、实现相关 | MB 级、实现相关 |
Web Storage API 是同步的。若一次序列化并写入 5MB JSON,会同时消耗 stringify、复制和存储时间,可能阻塞主线程;大数据、索引查询和事务需求应使用 IndexedDB 等异步存储。
六、登录态与跨标签页语义
HttpOnly Cookie 防止脚本直接读取会话值,但 XSS 仍可在页面同源上下文中代用户发请求,因此它是减轻凭证窃取而非治愈 XSS。Cookie 登录还要结合 Secure、合适的 SameSite、CSRF token/Origin 校验;跨站确需 SameSite=None 时必须配 Secure。
localStorage 在同源标签页间共享,其他文档会收到 storage 事件,发起修改的当前文档本身不会靠该事件收到通知。sessionStorage 按标签页/顶层浏览上下文隔离;通过 opener 打开的新页面可能获得初始副本,但之后两边独立,不能把它当可靠跨标签通道。
服务端会话:Set-Cookie(HttpOnly) → 浏览器自动携带 → 服务端校验
前端 token:JS 读取存储 → Authorization 头 → 服务端校验
假设长期 token 有效 30 天,一次 XSS 窃取可能把风险延长 30 天;改为 15 分钟 access token 只能缩短窗口,若刷新凭证同样可读仍未解决根因。安全设计要同时控制 XSS 注入面、凭证可读性、有效期、撤销和 CSRF。
选择存储先问三件事:是否要自动随请求发送、数据要活多久、同源脚本被攻破时能造成什么损失。
七、常见误区与追问
- 误区:HttpOnly Cookie 可以彻底防止 XSS。 它只阻止 JS 读取 Cookie,恶意脚本仍可操作页面并发起同源请求。
- 误区:localStorage 容量大,所以适合保存任意业务数据。 它同步、配额有限且无事务,不适合大对象与权威状态。
- 误区:sessionStorage 在所有新标签页之间绝对不共享。 新窗口可能从 opener 获得初始副本,但之后各自独立,具体还受打开方式影响。
- 追问:SameSite 的 site 和 same-origin 一样吗? 不一样,SameSite 按站点语义判断,而 origin 还严格包含协议、主机和端口。
- 追问:为什么 Cookie 过多会影响性能? 匹配 Cookie 会进入请求头,每个请求都可能重复传输,增大上行字节和服务端解析成本。
- 追问:跨标签页如何通知退出登录? 可用
storage事件、BroadcastChannel 等通知,但服务端会话撤销才是最终权威。 - 追问:何时使用 IndexedDB? 数据量较大、需要异步读写、索引或事务时,比同步 Web Storage 更合适。
八、加强记忆
Cookie 是受作用域和安全属性控制的 HTTP 状态,会自动随匹配请求发送;localStorage 是同源持久同步存储,sessionStorage 是标签页会话级同步存储。登录态没有万能存放点:HttpOnly 降低直接窃取,SameSite/Token 防 CSRF,输出编码与 CSP 防 XSS,服务端还要控制期限和撤销;大数据则转向 IndexedDB。