先记住这个答案
sessionStorage的数据归属于当前顶层浏览上下文(即标签页)。刷新当前页面时数据保留,可用于恢复临时状态;关闭标签页或浏览器窗口则终止会话并清除数据。通过window.open打开且保留opener时,新页面会复制一份初始快照,但之后读写互不影响。直接新建标签页或地址栏输入则得到空白存储。
- 刷新页面数据不丢失
- 关闭标签页即清除会话数据
- 新标签页独立,可复制初始值
存储分区与会话续存规则
sessionStorage以“源+顶层浏览上下文”为分区键,每个标签页保存独立的Storage对象。刷新页面时,浏览器复用该标签页的会话,存储数据继续存在。而localStorage按源共享,sessionStorage则与标签页强绑定,这是两者最核心的生命周期差异。
通过window.open打开新窗口且保留opener时,新页面的sessionStorage会先复制一份源页面的内容,但写入互不影响。为阻止这种复制,可使用rel=noopener或显式清除opener。直接输入地址或普通链接跳转不会复制,新标签页得到空白会话存储。
表单草稿:刷新恢复与关闭即删
一个多步骤问卷调查,用户填写过程中可能按F5刷新。开发者在change事件中将输入JSON序列化后写入sessionStorage,页面加载时读取并还原。由于刷新不终止标签页会话,草稿可恢复;关闭标签页后,sessionStorage自动清空,无需手动删除。
若使用localStorage,刷新也能读取,但关闭后数据仍保留,下次访问会残留旧草稿。sessionStorage恰好匹配“单次访问草稿”需求:存活于刷新与恢复,消亡于标签页关闭。这避免了额外清理逻辑,也减少误删风险。
生命周期边界与隐蔽例外
sessionStorage生命周期并非在所有关闭场景下都立即清除。例如浏览器崩溃后若恢复了标签页,部分浏览器会保留原有sessionStorage内容;用户通过“关闭其他标签页”不影响当前标签页,但浏览器扩展或强制清理可能改变行为。因此不可把“关闭标签页即清除”当作绝对保证。
若要严格保证数据只存在于单次页面会话,应在退出流程中主动调用removeItem或clear。复制标签页会复制初始快照,后续独立;若希望每次打开都是全新会话,可在打开链接时用rel=noopener阻止opener关联。将这些边界纳入设计,避免数据串号或残留。
容易答错的地方
- 刷新会清空sessionStorage
- 错误认为刷新相当于重新开会话。实际上刷新只是重新加载文档,仍处于同一顶层浏览上下文,sessionStorage数据保留。只有关闭标签页或浏览器进程结束才会清除。
- 新开标签页能共享sessionStorage
- 直接通过地址栏或普通链接打开的新标签页,没有opener关联,得到的是全新空白存储。只有通过window.open且保留opener时才可能复制初始值,但之后两边互不影响。
面试官还会怎么问?
sessionStorage能跨标签页共享吗?
不能直接共享。通过window.open打开的新标签页会继承一份初始副本,但之后写入互不影响。如果需要同步,应改用localStorage加storage事件或BroadcastChannel实现。
刷新与关闭后重新打开对sessionStorage有何不同?
刷新是同一页面会话延续,数据保留;关闭标签页后再打开属于全新会话,sessionStorage会重新创建并置空。这正是它与localStorage在生命周期上的关键差异。
如何判断当前标签页的sessionStorage是否被复制?
可检查window.opener是否非空且同源,若存在则初始值可能来自来源页面,但无法追溯完整历史。更可靠的方式是在页面启动时写入一个唯一会话标识,后续通过标识有效性判断是否新会话。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。