localStorage / sessionStorage / Cookie

1. 核心对比

特性CookielocalStoragesessionStorage
存储容量极小 (4KB)大 (~5MB)大 (~5MB)
生命周期默认会话级 (Session cookie),设置过期时间后可持久化永久有效,除非手动清除窗口关闭即销毁 (Tab级)
服务端通信每次 HTTP 请求都会自动携带不参与通信,仅在前端使用不参与通信,仅在前端使用
访问权限同源同源同源
安全性可设置 HttpOnly 防止 JS 访问无法设置,易被 XSS 攻击无法设置,易被 XSS 攻击

2. 详细解析

最古老的机制,设计初衷是让无状态的 HTTP 能够标识用户状态(Session ID)。因为每次请求都会带上,所以如果存储无用数据,会浪费带宽

关键属性:

  • HttpOnly: 禁止 document.cookie 访问,防止 XSS 攻击窃取 Token。
  • Secure: 仅在 HTTPS 传输。
  • SameSite: 防止 CSRF 攻击 (Strict, Lax, None)。
    • Strict: 完全禁止第三方 Cookie 发送。
    • Lax (默认): GET 导航等安全操作允许发送。

(2) localStorage

适合存储较大且不需要随请求发送的数据。例如:

  • 用户偏好设置(主题颜色、字体大小)。
  • 长效缓存的数据(如省市区列表)。

(3) sessionStorage

生命周期仅限于当前标签页 (Tab)。如果用户打开两个该网站的标签页,它们的 sessionStorage 是隔离的。适合存储临时表单数据、单次访问的状态。

(面试题:sessionStorage 在新开标签页可以共享吗?- 只有通过 window.opentarget="_blank" 打开的同源标签才有可能复制旧 Session,通常是独立的。)

3. 面试加分项:indexedDB

当存储空间需求极大 (> 50MB) 或需要更复杂的事务支持/索引查询时,应使用 IndexedDB。它是浏览器内置的非关系型数据库,支持二进制存储。

4. 常见问题 (FAQ)

Q: 如何防止 XSS 攻击读取 Token?

不要将 Token 存放在 localStorage 中,一旦脚本注入就能轻易窃取。 最佳实践:Token 存放在 HttpOnly Cookie 中,这样脚本无法读取,但 API 请求会自动带上。配合 CSRF Token 防御 CSRF。

Q: localStorage 有过期时间吗?

原生没有。需要手动封装:存储时写入 { value, expire: Date.now() + 1000 },读取时判断是否过期,过期则删除。