5月28日 01:18

Cookie 和 LocalStorage 有什么区别?什么场景该用哪个?

核心答案

Cookie 和 LocalStorage 都是浏览器的客户端存储机制,核心区别在于:Cookie 每次请求自动携带到服务器,容量约 4KB,适合存服务端需要的数据(如会话 ID);LocalStorage 不参与网络请求,容量 5-10MB,适合纯客户端的持久化数据(如用户偏好)。

两者选择的关键判断标准是:数据是否需要服务端读取。需要则 Cookie,不需要则 LocalStorage。

容量与生命周期

维度CookieLocalStorage
容量单条约 4KB,每域名 50 个左右每域名 5-10MB
生命周期可设 Expires/Max-Age,也支持会话级(浏览器关闭即失效)永久存储,除非手动清除
作用域Domain + Path 精确控制,可跨子域严格同源(协议+域名+端口)

网络行为差异

Cookie 最本质的特征是自动随 HTTP 请求发送。这意味着:

  • 优势:服务端无需额外代码即可读取,适合身份认证、个性化等场景
  • 劣势:每次请求都携带,增加带宽开销;大量冗余数据会拖慢请求

LocalStorage 的数据完全留在客户端,不会自动发送:

  • 优势:不占用请求带宽,存储空间大
  • 劣势:服务端无法直接获取,需要 JS 读取后通过请求体或 Header 手动传递

API 对比

javascript
// Cookie —— 字符串拼接,解析麻烦 document.cookie = "token=abc123; path=/; max-age=3600; secure; samesite=strict"; // 读取需要手动解析 document.cookie 字符串 // LocalStorage —— 键值对 API,直观简洁 localStorage.setItem("theme", "dark"); localStorage.getItem("theme"); // "dark" localStorage.removeItem("theme"); localStorage.clear();

实际项目中操作 Cookie 推荐使用 js-cookie 等库,避免手写解析逻辑。

安全性

这是面试高频追问点:

  • XSS 防护:Cookie 可设置 HttpOnly 标志,阻止 JS 读取,即使页面被注入恶意脚本也无法窃取 Cookie 内容;LocalStorage 没有此机制,任何 XSS 漏洞都能读取全部数据
  • CSRF 防护:Cookie 自动携带导致容易遭受 CSRF 攻击,需配合 SameSite 属性或 CSRF Token 防御;LocalStorage 不自动发送,天然免疫 CSRF
  • 传输安全:Cookie 可设 Secure 标志确保仅 HTTPS 下发送;LocalStorage 无此属性,但数据本身不参与传输

SameSite 属性三个值:

  • Strict:完全禁止跨站发送,最安全但影响体验(从外部链接跳转不带 Cookie)
  • Lax:导航到目标网站的 GET 请求允许携带,是现代浏览器默认值
  • None:允许跨站发送,必须同时设置 Secure

使用场景决策

选 Cookie 的场景:

  • 会话管理:登录态 Session ID / JWT Refresh Token
  • 服务端需要读取的偏好:语言、地区
  • CSRF 防护 Token 的双提交模式
  • A/B 测试分桶标识

选 LocalStorage 的场景:

  • 用户偏好:主题、布局、字号
  • 业务缓存:接口数据快照、表单草稿
  • 离线应用数据:PWA 缓存资源
  • 第三方库配置:编辑器工具栏状态

现代认证的混合方案(2025 实践):

  1. 短期 Access Token 存在内存中(5-15 分钟过期)
  2. 长期 Refresh Token 存在 HttpOnly + Secure + SameSite=Strict 的 Cookie 中
  3. LocalStorage 仅存非敏感的用户偏好

这种方案兼顾了 XSS 和 CSRF 两方面的安全防护。

追问

1. Cookie、LocalStorage、SessionStorage 三者怎么选? SessionStorage 与 LocalStorage API 完全一致,区别在于生命周期——标签页关闭即清除。适合临时性数据:表单填写进度、单次会话的搜索条件、多步骤向导的状态。

2. Cookie 的 SameSite 属性解决了什么问题?默认值是什么? 解决 CSRF 攻击问题。Chrome 80+ 默认值为 Lax,允许顶级导航的 GET 请求携带 Cookie,但阻止跨站 POST 请求携带。

3. 如果 LocalStorage 被 XSS 攻击读取了怎么办? 核心原则:LocalStorage 中不要存敏感数据(密码、Token)。已被窃取的数据无法撤回,只能立即让用户重置密码、吊销旧 Token。防御重点在前端输入过滤和 CSP 策略。

4. 超过 LocalStorage 5MB 限制会怎样? 写入操作抛出 QuotaExceededError 异常。实际项目中应做好 try-catch 和容量监控,或在写入前用 JSON.stringify(data).length 估算占用。

5. 跨域下 Cookie 和 LocalStorage 的表现有什么不同? Cookie 可通过设置 Domain=.example.com 实现主域名下子域共享;LocalStorage 严格同源,不同子域各自独立,跨域共享需要 postMessage 等方案中转。

标签:Cookie