浏览器存储详解
1. 核心存储方式对比
2. 深度解析
(1) Cookie
最古老的机制,设计初衷是维持 HTTP 状态 (Session ID) 而非存储数据。
关键属性 (面试题):
HttpOnly: 禁止 JavaScript 访问 (document.cookie),防止 XSS 攻击窃取 Token。Secure: 仅在 HTTPS 传输。SameSite: 防止 CSRF 攻击 (Strict, Lax, None)。Strict: 禁止第三方请求携带。Lax(默认): 允许安全的顶级导航 (如链接跳转) 携带。
缺陷:
- 性能损耗:由于每次请求都会带上 Cookie,如果存了几 KB 无关数据,会严重浪费带宽。
- 容量太小:仅 4KB。
(2) localStorage
适合场景:长期保存的非敏感数据。
- 用户偏好设置 (Theme, Language)。
- 简单的应用状态持久化。
- 长效缓存 (如静态数据字典)。
注意:
- 虽大但有限:5MB 满了会报错 (QuotaExceededError),需 try-catch。
- 同步阻塞:读写操作是同步的,读写大数据会阻塞主线程。
(3) sessionStorage
适合场景:单次会话的临时数据。
- 表单分步填写数据 (防止刷新丢失)。
- 一次性登录状态 (如某些后台管理系统)。
面试题:新开标签页 sessionStorage 会共享吗?
- 不会。sessionStorage 是基于 Top-Level Browsing Context 的,即使同源,不同 Tab 也是隔离的。
- 特例:通过
window.open或<a target="_blank">打开的新标签页,在某些浏览器 (如 Chrome) 会复制旧页面的 sessionStorage,但之后互不影响。
(4) IndexedDB
浏览器内置的非关系型数据库 (NoSQL)。
特点:
- 异步:读写不会阻塞主线程。
- 支持二进制:可直接存
ArrayBuffer,Blob(图片/文件)。 - 事务:支持 ACID。
- 索引:支持高性能查询。
场景:
- 离线应用 (PWA) 的大量数据存储。
- 编辑器应用 (如 VSCode Web) 缓存文件内容。
3. 安全性最佳实践
Q: Token 应该存在哪?
这是一个经典的面试争论题。
-
方案 A (localStorage):
- 优点:简单,前端控制力强,方便加到 Header (
Authorization: Bearer ...)。 - 缺点:容易被 XSS 攻击窃取 (一个
localStorage.getItem就偷走了)。需配合严谨的 XSS 防御。
- 优点:简单,前端控制力强,方便加到 Header (
-
方案 B (HttpOnly Cookie):
- 优点:JS 无法读取,天然免疫 XSS 窃取。
- 缺点:容易被 CSRF 攻击 (跨站伪造请求)。需配合 CSRF Token 或 SameSite 属性。
- 推荐:对于高安全性要求,使用 HttpOnly Cookie + CSRF Token 是业界标准。
Q: 如何手动实现 localStorage 过期?
原生不支持。封装时存入 { value, expire: Date.now() + 1000 }。读取时判断 Date.now() > expire,如果超时则 removeItem 并返回 null。

