选 sessionStorage 还是 localStorage,关键不在 API 写法,而在数据“活多久”和“被谁用”:sessionStorage 仅限单标签页、关闭即清空,适合临时状态;localStorage 跨标签页持久保存,适合长期缓存。

选 sessionStorage 还是 localStorage,关键不在 API 写法,而在数据“活多久”和“被谁用”。用错一个,状态就乱——不是报错,而是用户感知到异常。
看数据要不要跨标签页共享
localStorage 是同源下所有标签页共用的。比如用户开了两个管理后台页面,A 标签页切换了主题色,B 标签页立刻同步生效;但这也意味着 A 和 B 同时改同一个 key(如 cartItems),后写入的会直接覆盖前写入的,且无提示。
sessionStorage 则完全隔离:每个标签页有自己独立的存储空间。适合需要“互不干扰”的场景:
- 多步骤表单(地址→支付→确认),每步存中间状态,关掉当前页就清空,不污染其他流程
- 单页应用中某模块的临时筛选条件(如日志列表的时间范围),刷新保留,换标签页不影响
- 嵌套同源 iframe 间需共享临时上下文(如父页与子 iframe 共用 session 数据)
看数据是否必须撑过浏览器重启
localStorage 的数据写进去就“钉”在硬盘上,除非用户手动清除、代码调用 clear() 或浏览器强制清理缓存,否则一直存在。适合长期偏好类信息:
- 用户选择的语言、深色模式开关
- 折叠/展开的菜单状态、表格列宽配置
- 离线可用的静态资源哈希(如词典、图标集元数据)
sessionStorage 在关闭整个浏览器窗口(哪怕只关一个标签页)后即销毁。它撑不过刷新?错——刷新不会清空;但它撑不过“关掉这个标签页”。别把它当登录态存,否则用户新开标签页就得重新登录。
看有没有并发写入风险
两者都无内置锁机制,纯覆盖式写入。但 localStorage 因跨页共享,更容易出现竞态:
- 用户在 A 标签页编辑草稿并保存,同时在 B 标签页也编辑同一份,B 提交后 A 的本地副本就被覆盖了
- 多个标签页监听
storage事件做 UI 更新,但事件无法阻止写入,只能响应
sessionStorage 天然规避这类问题——每个标签页自管自的数据,写入互不影响。若业务逻辑本身要求“单实例操作”,它反而更安全。
看浏览器兼容与容量是否可靠
别轻信“5MB”标称值。实际可用空间浮动很大:
- Safari 无痕模式下可能连 100KB 都不给,
setItem直接抛QuotaExceededError - Chrome 正常模式约 10MB,但磁盘紧张时也会降级
- 检测是否真正可用,不能只判断
typeof localStorage !== 'undefined',得try { localStorage.setItem('test', 'x'); localStorage.removeItem('test'); } catch(e) { /* 不可用 */ }
sessionStorage 同样受此限制,但因生命周期短,出问题影响范围小;localStorage 若用于关键缓存,务必加兜底逻辑(如降级到内存变量或 fallback 请求)。


















