localstorage 和 sessionstorage 的核心区别在于生命周期与作用域:localstorage 数据长期保存且同源页面共享,sessionstorage 仅限当前标签页会话、关闭即清除且各标签页独立。

sessionStorage 和 localStorage 的基本行为在所有现代浏览器中高度一致,但实际项目中遇到的“奇怪表现”,往往来自几个被忽略的细微差别。这些差异不常写在文档里,却直接影响多标签页协作、隐私模式兼容、甚至 iOS Safari 的表单恢复逻辑。
同源判定细节:端口和协议更严格
虽然都遵循同源策略,但部分浏览器(尤其是旧版 Edge 和某些 Android WebView)对端口和协议的判定存在宽松或严格倾向:
- localhost:3000 和 localhost:3001 被视为不同源 → localStorage 不共享,这是标准行为;但个别低版本 WebView 曾错误地将它们当作同一源,导致数据意外泄露
- HTTP 和 HTTPS 页面即使域名相同,也绝对隔离 → 但若页面通过 meta 标签或 CSP 混合内容策略降级加载,某些 Safari 版本会拒绝写入 localStorage,却允许 sessionStorage 写入(因不涉及跨域持久化)
iOS Safari 的 sessionStorage 特殊处理
iOS Safari(特别是 16.x–17.x)对 sessionStorage 的生命周期做了隐式延长:
- 用户从标签页切换到后台(非强制关闭),再切回时,sessionStorage 数据仍存在 —— 这不同于桌面 Safari 或 Chrome 的“标签页关闭即清除”语义
- 当用户使用“滑动关闭标签页”手势时,iOS Safari 实际延迟清理 sessionStorage,若此时快速重建同 URL 标签页,偶发复用旧 session 数据(非 bug,是渲染进程复用机制所致)
隐私/无痕模式下的行为分化
隐私模式不是“统一清零”,而是按存储类型区别对待:
- Chrome / Edge:localStorage 在无痕窗口中可用,但关闭窗口后立即销毁;sessionStorage 行为与普通模式一致
- Safari:localStorage 在无痕模式下完全禁用(getItem/setItem 均返回 null 或静默失败),而 sessionStorage 仍可读写,仅在标签页关闭时清除
- Firefox:两者均可用,但 localStorage 数据仅存活于当前无痕会话,重启浏览器后自动清空 —— 注意这和“永久存储”的常规理解冲突
iframe 中的 storage 作用域继承规则
父页面与 iframe 共享 localStorage 是常见误区。真实情况是:
- 同源 iframe:localStorage 完全共享(父页 set,子 iframe 可 get)
- 同源但不同路径的 iframe(如 /app 和 /admin):仍属同源,localStorage 共享 ✅
- sessionStorage:即使同源,父页与 iframe 也各自独立维护 —— 但有一个例外:若 iframe 由父页 JS 动态创建(非 HTML src 声明),且未指定 sandbox 属性,则部分 Chromium 版本会继承父页的 sessionStorage 上下文











