前端存储:LocalStorage、SessionStorage 与 Cookie

FreeGuideOnline 最新 2026-06-15

前端存储完全指南:LocalStorage、SessionStorage 与 Cookie

在构建现代 Web 应用时,客户端数据存储是一个无法绕开的话题。无论是记住用户偏好、保持登录状态,还是缓存数据以提升性能,都离不开前端存储机制。本教程将带你系统掌握三种最基础的浏览器存储方案:CookieLocalStorageSessionStorage。我们将从概念、CRUD 操作、适用场景到安全实践,逐一拆解,让你在实战中游刃有余。


一、为何需要前端存储?

HTTP 协议本身是无状态的,这意味着服务器不会自动“记住”上一次请求是谁发出的。为了让 Web 应用具备记忆能力,我们需要在客户端保存一些关键数据。常见的需求包括:

  • 用户登录后,在一段时间内保持认证状态。
  • 记住用户的主题偏好、语言设置。
  • 表单自动填充,提升用户体验。
  • 缓存接口数据,减少重复请求。

围绕这些目标,浏览器提供了多种存储方式,其中 CookieLocalStorageSessionStorage 是最基础、最常打交道的三种。


二、LocalStorage:持久化的本地仓库

2.1 什么是 LocalStorage?

LocalStorage 是浏览器提供的键值对存储机制,属于 Web Storage API 的一部分。数据保存在用户的本地磁盘中,没有过期时间,除非用户手动清除或应用主动删除,否则数据会永久存在。

2.2 基本特点

  • 容量大:通常每个域名有 5MB 的存储空间(不同浏览器略有差异)。
  • 仅客户端访问:数据不会自动随 HTTP 请求发送到服务器。
  • 同源策略:协议、域名、端口三者必须完全相同,才能访问同一份 Storage。
  • 同步 API:操作是同步的(少数浏览器实现可能异步,但标准是同步),调用后会立即阻塞后续代码,不宜存储过大数据或进行大量读写操作。
  • 仅支持字符串:键和值都必须是字符串。若需存储对象,必须用 JSON.stringify() 转换,读取时再用 JSON.parse() 复原。

2.3 核心 API

// 存储数据
localStorage.setItem('username', 'Alice');
localStorage.setItem('settings', JSON.stringify({ theme: 'dark' }));

// 读取数据
const name = localStorage.getItem('username');          // 'Alice'
const settings = JSON.parse(localStorage.getItem('settings')); // { theme: 'dark' }

// 移除单个键
localStorage.removeItem('username');

// 清空当前域名下所有存储
localStorage.clear();

// 获取第 n 个键名(不常用)
const keyName = localStorage.key(0);

// 获取存储的键值对数量
const len = localStorage.length;

2.4 典型应用场景

  • 长期保存用户偏好:如主题颜色、字体大小、首页布局等。
  • 离线数据缓存:将不常变的接口数据缓存在本地,减少网络请求。
  • 草稿保存:在用户编辑长篇内容时,自动保存至 LocalStorage,防止意外丢失。

2.5 注意事项与安全风险

  • 不要存储敏感信息:LocalStorage 可以被任何同源下的 JavaScript 轻松读取,XSS 攻击一旦成功,所有数据都将暴露。
  • 无法跨域共享:同一个网页在不同域名下存储的数据完全隔离。
  • 存储空间检测:虽然一般有 5MB,但不宜写满。可使用 try...catch 捕获超出配额的异常。
  • 清除策略:用户可能在浏览器设置中“清除浏览数据”时删除 LocalStorage,不要依赖它作为唯一持久化手段。

三、SessionStorage:会话级别的临时存储

3.1 什么是 SessionStorage?

SessionStorage 同样是 Web Storage API 的一部分,API 与 LocalStorage 完全一致,但数据生命周期完全不同:数据仅在当前浏览器标签或窗口的会话期间有效。一旦关闭标签页或窗口,所有数据即被清除。甚至同一网站在新标签页打开时,也会拥有不同的 SessionStorage 实例。

3.2 核心特点

  • 会话隔离:每个标签页或窗口拥有独立的 SessionStorage,无法跨标签访问。
  • 容量限制:通常也是 5MB(同 LocalStorage)。
  • 同步操作:与 LocalStorage 一样。
  • 不会发送到服务器:纯粹客户端存储。

3.3 API 一览

与 LocalStorage 完全一致,只需将 localStorage 替换为 sessionStorage

sessionStorage.setItem('tempData', 'some value');
sessionStorage.getItem('tempData');
sessionStorage.removeItem('tempData');
sessionStorage.clear();

3.4 典型应用场景

  • 单次流程中的临时状态:例如多步骤表单(购物车结算流程),用户切换步骤时数据不丢失,但关闭页面后无需保留。
  • 敏感操作的临时令牌:要求每次打开标签页都重新登录的高安全场景(如网银操作界面),可将短期票据存于 SessionStorage,随标签关闭自动销毁。
  • 避免页面刷新丢失弹层状态:记录“已展示过新手引导”、“已关闭活动弹窗”等,仅对当前会话有效。

3.5 与 LocalStorage 的关键区别

特性 LocalStorage SessionStorage
生命周期 永久(除非手动删除) 标签页关闭即销毁
作用范围 同源所有标签页共享 仅限当前标签页
存储新标签打开时 与已打开页面共享 不共享,完全独立
典型用途 持久化用户偏好、缓存 临时状态、单次会话数据

Cookie 是服务器通过 HTTP 响应头发给浏览器的一小段文本数据,浏览器会按规则自动保存,并在后续请求中自动带上。它最初是为解决 HTTP 无状态问题而生的,至今仍是实现会话保持的重要手段。

  • 大小极小:单个 Cookie 不能超过 4KB,每个域名下的 Cookie 总数通常限制在 20 ~ 50 个(不同浏览器不同)。
  • 自动发送:每次满足条件的 HTTP 请求,都会自动携带 Cookie,会消耗额外流量,影响请求速度。
  • 可设置过期时间:若不设置 ExpiresMax-Age,则为会话 Cookie,浏览器关闭即失效;若设置了过期时间,则会在指定时间后清除。
  • 支持可配置的作用域:通过 PathDomain 属性控制 Cookie 对哪些路径和域名生效。
  • 安全属性丰富:可设置 HttpOnly(禁止 JS 访问)、Secure(仅 HTTPS 传输)、SameSite(防 CSRF)等,安全性比 Storage 更高。

浏览器并未提供优雅的 Cookie API,需要手动封装解析函数。读取当前页面可访问的 Cookie(非 HttpOnly 的)可通过 document.cookie

// 设置 Cookie
document.cookie = "username=Alice; path=/; max-age=604800"; // 有效期 7 天

// 删除 Cookie:设置过期时间为过去
document.cookie = "username=; path=/; max-age=0";

// 读取所有 Cookie(得到一个包含所有键值对的字符串)
const allCookies = document.cookie; // "username=Alice; theme=dark"

// 封装一个读取指定 key 的函数
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

注意:如果是 HttpOnly 标记的 Cookie,document.cookie 无法读取,JavaScript 完全不可访问,这能有效防御 XSS 窃取会话 ID。

4.4 常用场景

  • 会话管理:登录后的 Session ID 或 Token 通常存放在 Cookie 中(后端设置 HttpOnly 防止 JS 读取),由浏览器自动携带,实现身份识别。
  • 个性化设置:在不依赖 JavaScript 的情况下,通过 Cookie 记录用户语言、地区等(例如服务端渲染页面可读取 Cookie 直接输出对应内容)。
  • 跨页面轻量级数据:当需要将少量数据在多个页面间甚至不同子域间共享时,Cookie 的 Domain 属性可以派上用场。
  • 追踪与分析:第三方追踪脚本常利用 Cookie 记录用户行为(但现在越来越受限)。

4.5 安全实践

  • 始终设置 Secure 属性,确保 Cookie 只在 HTTPS 连接下传输,防止中间人攻击。
  • 为会话标识设置 HttpOnly,杜绝 JavaScript 接触到敏感凭证。
  • 合理配置 SameSite 属性,将其设为 StrictLax 可有效缓解 CSRF 攻击。
  • 设置较短的过期时间,避免长期保留敏感凭证。
  • 限制 DomainPath,遵循最小权限原则,只让必需的路径和子域访问 Cookie。

五、三者的横向对比与选择指南

维度 LocalStorage SessionStorage Cookie
容量 约 5MB 约 5MB 约 4KB/个,总数限制
生命周期 永久(手动删除或清缓存) 标签关闭后清除 可设置过期,默认会话结束清除
作用域 同源所有标签页共享 仅限当前标签页 同源(可跨子域),按 Path/Domain 限制
是否发送至服务端 是,每次符合规则的请求自动携带
API 易用性 简洁的同步 API 与 LocalStorage 相同 原始字符串操作,需手动封装
安全性 易受 XSS 攻击,不宜存敏感数据 同 LocalStorage 可设置 HttpOnly/Secure 等多种防护
典型用途 持久化非敏感偏好、本地缓存 临时状态、单次流程 身份认证、跟踪、服务端可读数据

如何选择?

  • 你需要存储 大量、不敏感的客户端数据,并在用户下次访问时仍可用 → LocalStorage
  • 你需要存储 仅在当前标签页有效的数据,关闭标签页即丢弃 → SessionStorage
  • 你需要 每次请求自动携带数据(如认证令牌),并且希望 服务端可以参与读写Cookie
  • 涉及 敏感凭证 → 优先选择 HttpOnly + Secure 的 Cookie,避免使用 Storage。
  • 数据 不需要持久化且不可被用户轻易篡改 → 结合后端会话,Cookie 仍是经典之选。

六、综合示例:记住主题偏好实现

下面通过一个实际场景串联三者:实现“深色/浅色主题切换”,并记录偏好。

需求:用户切换主题后,刷新页面仍保持所选主题;但用户在隐私模式或不同标签下不应持久化?这里选择 LocalStorage 作为持久化方案。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>主题切换</title>
  <style>
    body.dark-mode { background: #1e1e1e; color: #fff; }
  </style>
</head>
<body>
  <button id="themeToggle">切换深色模式</button>

  <script>
    const body = document.body;
    const btn = document.getElementById('themeToggle');

    // 初始化主题
    const savedTheme = localStorage.getItem('theme');
    if (savedTheme === 'dark') {
      body.classList.add('dark-mode');
    }

    btn.addEventListener('click', () => {
      body.classList.toggle('dark-mode');
      const currentTheme = body.classList.contains('dark-mode') ? 'dark' : 'light';
      // 将当前偏好存入 LocalStorage
      localStorage.setItem('theme', currentTheme);
    });
  </script>
</body>
</html>

此例用 LocalStorage 长期记住选择。如果需求是“仅在本次浏览过程中记住选择,关闭标签页后恢复默认”,将 localStorage 改为 sessionStorage 即可。如果希望服务端在渲染页面时就能知道用户的主题,则可将主题写入 Cookie,由后端读取并输出对应的 CSS 类名。


七、常见问题与调试技巧

7.1 如何查看当前存储的数据?

所有主流浏览器均提供了开发者工具:

  • Chrome/Edge:F12 → Application(应用程序)→ Storage(存储)栏,可查看 Local Storage、Session Storage 和 Cookies。
  • Firefox:F12 → Storage(存储)选项卡。
  • Safari:开发菜单 → 显示 Web 检查器 → “存储”标签。

你可以直接在这里编辑、删除或添加条目,非常适合调试。

检查以下几点:

  • Cookie 的 Path 是否匹配当前请求路径?
  • Domain 是否与当前域名匹配(包括子域)?
  • 是否设置了 Secure,但当前页面是 HTTP?
  • SameSite 属性是否阻止了第三方请求发送 Cookie?例如 SameSite=Strict 在链接跳转时可能不会发送。根据具体情况调整为 Lax

7.3 LocalStorage 容量满了怎么办?

可以监听 windowstorage 事件(跨标签页同步时触发,但不会在当前页面自我触发),或使用 try...catch 捕获 setItem 抛出的 QuotaExceededError。解决方案:

  • 清理无用数据。
  • 将过大的数据迁移到 IndexedDB(容量更大,支持异步)。
  • 提示用户手动释放空间。

八、总结与扩展思考

LocalStorage、SessionStorage 和 Cookie 构成了前端存储的基石。它们各有优缺点,不存在一个万能的方案。理解它们的工作机制、生命周期和安全边界,才能在实际业务中选择合适的工具。

随着 Web 应用日益复杂,你还会接触到更强大的存储方案,例如 IndexedDB(适合大量结构化数据的异步存储)、Service Worker 与 Cache API(用于离线应用和资源缓存)。但无论技术如何演进,基础存储原理始终相通。建议你在掌握本文内容后,亲手实践几个场景,体会不同存储策略带来的架构影响。

记住核心原则:敏感数据永远不要放在客户端可被随意读取的地方,任何客户端存储的数据都只是“便利贴”,永远不要当作唯一可信源。