浏览器存储:localStorage / sessionStorage / cookie 应该怎么用

同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~

(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)

你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?

你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?

就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。

一天只有24小时,时间永远不够用,常常感到力不从心。

技术行业,本就是逆水行舟,不进则退。

如果你也有同样的困扰,别慌。

从现在开始,跟着我一起心态归零 ,利用碎片时间,来一次彻彻底底的基础扫盲

这一次,我们一起慢慢来,扎扎实实变强。

不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,

咱们一起稳步积累,真正摆脱"面向搜索引擎写代码"的尴尬。


一、开篇:为什么要关心浏览器存储?

日常开发里经常会遇到:

  • Token 存哪:登录后 token 放在哪、刷新页面怎么不丢?
  • 用户配置:主题、语言、侧边栏收起状态,下次打开要记住。
  • 列表筛选:表格的筛选条件、分页、排序,希望刷新后还能保留。

这些都要用到浏览器存储。但 localStorage、sessionStorage、cookie 该怎么选?场景对应错了,就会有跨 tab 不同步、隐私泄露、存不下等问题。

下面从概念 → 用法 → 实战场景 → 选型 → 踩坑 ,把三者讲清楚:日常该用哪个、为什么这么用、容易踩哪些坑


二、概念扫盲

先用一张表看清三者区别:

特性 localStorage sessionStorage cookie
生命周期 持久化,除非手动删除 关闭标签页即失效 可设置过期时间
容量 约 5MB 约 5MB 约 4KB
作用域 同源下所有页面共享 仅当前标签页 同源共享,可设置 path
是否随请求发送 是(每次请求自动带)
API 风格 getItem / setItem 同上 document.cookie 字符串操作

一句话记:

  • localStorage:长期存、全页面共享,适合偏好、配置。
  • sessionStorage:仅当前标签页、关掉就丢,适合临时状态。
  • cookie:每次请求都会带上,适合需和服务端交互的(如认证、会话)。

三、localStorage:持久化存储

3.1 是什么?

localStorage 是持久化存储,数据不会过期,除非主动删除,或用户清除浏览器数据。同源下所有页面共享。

3.2 基本用法

javascript 复制代码
// 存
localStorage.setItem('theme', 'dark');

// 取
const theme = localStorage.getItem('theme');  // 'dark'

// 删
localStorage.removeItem('theme');

// 清空所有
localStorage.clear();

注意:只能存字符串。对象需要序列化:

javascript 复制代码
// 存对象
const userConfig = { theme: 'dark', lang: 'zh' };
localStorage.setItem('userConfig', JSON.stringify(userConfig));

// 取对象
const config = JSON.parse(localStorage.getItem('userConfig') || '{}');

3.3 适用场景

  • 用户主题、语言、侧边栏状态
  • 需要持久化的列表筛选、排序、分页
  • 表单草稿(不敏感数据)
  • Token(前提是放在合理的安全体系里)

四、sessionStorage:会话级存储

4.1 是什么?

sessionStorage 的生命周期只到当前标签页关闭。新开标签页是新会话,数据不共享。

4.2 基本用法

javascript 复制代码
// 用法和 localStorage 一样
sessionStorage.setItem('tempId', 'abc123');
const tempId = sessionStorage.getItem('tempId');
sessionStorage.removeItem('tempId');

4.3 适用场景

  • 当前页的临时数据(如多步表单的中间页)
  • 不希望跨 tab 共享的数据
  • 表单防重复提交用的临时标记
  • 一些只对当前会话有用的临时 token

4.4 常见误区

很多人以为 sessionStorage 和"会话"一样,关浏览器才清空。实际上:

  • 关闭标签页 → 数据就没了
  • 刷新页面 → 数据还在
  • 新开标签页 → 新会话,看不到旧数据

五、cookie:会被请求携带的存储

5.1 是什么?

cookie 是早期方案,容量小,每次 HTTP 请求会自动带上(同域且 path 匹配时)。因此常用来存 sessionId、token 等需要和服务端交互的信息。

5.2 基本用法

cookie 需要手动拼字符串,原生 API 不友好:

javascript 复制代码
// 设置 cookie(需手动拼接)
document.cookie = 'token=abc123; path=/; max-age=3600';  // 1小时过期

// 读取 cookie
const cookies = document.cookie;  // "token=abc123; theme=dark"
// 需要自己解析
function getCookie(name) {
  const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
  return match ? match[2] : null;
}
getCookie('token');  // 'abc123'

常用属性说明:

属性 含义
path=/ 哪些路径会携带此 cookie
max-age=3600 多少秒后过期
domain=.example.com 子域名共享
Secure 仅 HTTPS 传输
HttpOnly 禁止 JS 访问,防 XSS 读 token

5.3 适用场景

  • 登录凭证(sessionId、token),尤其是需要服务端校验时
  • 与后端交互的会话状态
  • 老项目或接口强依赖 cookie 的场景

现代项目里,很多 token 用 localStorage 存,请求时通过 Authorization 头发送,而不再用 cookie。这取决于你的前后端约定和安全方案。


六、实战场景:该用哪个?

6.1 Token 存储

常见做法有三种:

方式 优点 缺点
localStorage 刷新不丢、跨 tab 共享、实现简单 易受 XSS 攻击读走 token
sessionStorage 关 tab 即失效,相对更安全 刷新会丢,需配合刷新 token 逻辑
cookie (HttpOnly) JS 无法读取,防 XSS 偷 token 需后端配合设置,前后端都要处理

建议

  • 大部分前后端分离项目:用 localStorage,配合 XSS 防护(输入过滤、CSP 等)。
  • 对安全要求高的项目:用 HttpOnly cookie,由后端设置。
  • 仅当前 tab 有效的临时 token:用 sessionStorage

示例(localStorage 存 token):

javascript 复制代码
// 登录成功后
const token = response.data.token;
localStorage.setItem('token', token);

// 请求拦截器里
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 退出登录
localStorage.removeItem('token');

6.2 用户配置(主题、语言等)

这类配置需要持久化,且希望下次打开还是同样的,用 localStorage

javascript 复制代码
// 封装一个简单的配置管理
const CONFIG_KEY = 'userConfig';

const defaultConfig = {
  theme: 'light',
  lang: 'zh',
  sidebarCollapsed: false
};

function getConfig() {
  try {
    const saved = localStorage.getItem(CONFIG_KEY);
    return saved ? { ...defaultConfig, ...JSON.parse(saved) } : { ...defaultConfig };
  } catch {
    return { ...defaultConfig };
  }
}

function setConfig(partial) {
  const config = { ...getConfig(), ...partial };
  localStorage.setItem(CONFIG_KEY, JSON.stringify(config));
  return config;
}

// 使用
setConfig({ theme: 'dark' });
const config = getConfig();

6.3 缓存查询条件(表格筛选、分页)

列表的筛选、排序、分页希望刷新后还能保留,用 localStorage

javascript 复制代码
const CACHE_KEY = 'userList_query';

// 进入页面时恢复
const savedQuery = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}');
this.filters = savedQuery.filters || {};
this.pagination = savedQuery.pagination || { page: 1, size: 10 };

// 筛选或分页变化时保存
function saveQuery(filters, pagination) {
  localStorage.setItem(CACHE_KEY, JSON.stringify({
    filters,
    pagination
  }));
}

// 清空筛选时清除
function clearQuery() {
  localStorage.removeItem(CACHE_KEY);
}

6.4 多步表单的中间状态

多步表单的中间页,只对当前 tab 有效,不希望跨 tab 共享,用 sessionStorage

javascript 复制代码
// 第二步填写时保存
sessionStorage.setItem('formStep2', JSON.stringify(formData));

// 第三步页面加载时恢复
const step2Data = JSON.parse(sessionStorage.getItem('formStep2') || '{}');

// 提交成功后清除
sessionStorage.removeItem('formStep2');

七、怎么选?一张表搞定

场景 推荐 理由
Token localStorage 或 HttpOnly cookie 持久、跨 tab;安全要求高用 cookie
用户主题、语言、配置 localStorage 持久化,刷新和重开都保留
列表筛选、分页、排序 localStorage 持久化,提升使用体验
多步表单中间状态 sessionStorage 仅当前 tab,关掉即清空
临时防重复提交标记 sessionStorage 仅当前会话有效
需要随请求自动携带的凭证 cookie 浏览器会自动带上

八、踩坑指南

原因 建议
存对象报错或乱码 只支持字符串 JSON.stringify 存,JSON.parse
私密模式下 localStorage 可能不可用 部分浏览器会限制或清空 用 try-catch 包一层,失败时降级到内存
跨 tab 不同步 localStorage 变更不会自动通知其他 tab 监听 storage 事件做同步
cookie 超出 4KB 单条 cookie 约 4KB 限制 大对象改用 localStorage,或拆分多个 cookie
测试环境数据残留 上次测试数据还在 测试前 localStorage.clear() 或单独用测试 key

storage 事件:跨 tab 同步

当其他 tab 修改了 localStorage,当前 tab 会触发 storage 事件:

javascript 复制代码
window.addEventListener('storage', (e) => {
  if (e.key === 'theme') {
    // 其他 tab 改了 theme,这里同步更新
    applyTheme(e.newValue);
  }
});

注意:修改 localStorage 的那个 tab 不会触发,只有其他同源页面会收到。


九、小结

存储方式 一句话 典型场景
localStorage 持久、同源共享、不随请求发送 用户配置、token、列表筛选缓存
sessionStorage 当前标签页有效、关掉即丢 多步表单、临时标记
cookie 容量小、随请求自动携带 需后端校验的登录凭证

记住三点:

  1. 需要持久化、跨 tab 用 localStorage;仅当前 tab、关掉就丢 用 sessionStorage。
  2. 需要随请求自动携带 用 cookie;否则优先用 localStorage/sessionStorage。
  3. 只存字符串 ,对象用 JSON.stringify/parse;注意容量(localStorage 约 5MB,cookie 约 4KB)。

选对存储方式,可以少很多莫名其妙的 bug,也更符合安全和性能预期。


学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。

后续我还会继续用这种大白话、讲实战方式,带大家扫盲更多前端基础。

关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。

如果你觉得这篇内容对你有帮助,不妨点赞收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。

我是 Eugene,你的电子学友,我们下一篇干货见~

相关推荐
Apifox2 小时前
Apifox 2 月更新|MCP Client 调试体验优化、测试套件持续升级、支持公用测试数据、测试报告优化
前端·后端·测试
敲敲了个代码2 小时前
vue文件自动生成路由会成为主流
开发语言·前端·javascript·vue.js·前端框架
程序员林北北2 小时前
【前端进阶之旅】typescriot的数据类型讲解(二)
前端·javascript·vue.js·react.js·typescript
霍理迪2 小时前
JS—事件高级
开发语言·javascript·ecmascript
火车叼位2 小时前
TypeScript 类型体操:如何精准控制可选参数的“去留”
前端·typescript
接着奏乐接着舞2 小时前
vue3面试题
前端·javascript·vue.js
xkxnq2 小时前
第六阶段:Vue生态高级整合与优化(第81天)(Pinia核心进阶)状态模块化设计+跨模块通信(storeToRefs使用避坑)
前端·javascript·vue.js
患得患失9492 小时前
【前端动画】FLIP 动画原则
前端
赵_叶紫3 小时前
Kubernetes 从入门到实践
前端