最近需要完成一个分屏和脱离主窗口的功能,因为我把是否分屏的状态保存到了sessionStorage中,所以以前的功能时发现了一个小问题,在通过window.open
打开的窗口会复用主窗口的sessionStorage,这就有奇怪了。sessionStorage的状态不是随着主窗口的存在而存在吗?
通过 window.open
打开的窗口复用当前窗口的 sessionStorage
,是由浏览器的同源策略和页面上下文继承机制决定的。以下是详细解释:
sessionStorag的基本规律
- 作用域:
sessionStorage
的作用域限定在 同源(协议+域名+端口) 下的单个浏览器标签页或窗口。 - 生命周期:数据仅在当前会话(标签页或窗口)有效,关闭标签页后数据销毁。
- 隔离性:默认情况下,不同标签页或窗口的
sessionStorage
是相互隔离的。
那结合window.open
又有啥魔法呢
通过 window.open(url, '_blank')
打开的新窗口如果满足下面两个条件,可以继承原窗口的 sessionStorage
:
- 同源:新窗口加载的 URL 与原窗口同源。
- 由脚本触发:新窗口通过 JavaScript 代码打开。这个也就可以区分是用户手动(右键菜单选择“在新标签页打开链接”)创建的还是有用户触发代码创建的
注意:window.open还可以指定第三个参数,用于在窗口当开tab页,只要同源也是可以共享sessionStorage的。
为何会出现这种现象呢?
-
浏览上下文继承:
通过window.open
打开的窗口,可能被视为原窗口的“子窗口”。浏览器会将原窗口的sessionStorage
复制到新窗口,但后续修改会独立(复制后两者不再同步)。 -
规范与实现差异:
HTML5 规范未明确规定此行为,因此不同浏览器实现可能不同。例如:- Chrome:复制
sessionStorage
。 - Firefox:不复制,新窗口的
sessionStorage
为空。 - Safari:行为可能随版本变化。
- Chrome:复制
总结
window.open
复用 sessionStorage
是浏览器对脚本打开 同源窗口的一种特殊处理,旨在保留上下文状态。但需注意不同浏览器的实现差异。
还有哪些方式可以共享主页面的sessionStorage呢
通过
嵌入的同源页面
父页面通过 嵌入同源的子页面。
内嵌的页面与父页面共享相同的
sessionStorage
,因为它们属于同一浏览上下文。如果用户手动在新标签页打开 的URL,
sessionStorage
将不共享。
html 代码解读复制代码
<iframe src="http://127.0.0.1:5500/b.html" frameborder="1">iframe>
通过 javascript:
导航的同源页面
通过 javascript:
协议在地址栏跳转或通过链接跳转。
某些浏览器可能会将此视为同一会话上下文(类似 window.open
),但此行为不统一且可能被拦截。
html 代码解读复制代码 <a href="javascript:window.open('http://127.0.0.1:5500/b.html')">打开新标签页a>
通过 target="_blank"
的同源链接(需特定条件)
在 标签中使用
target="_blank"
打开同源页面,且添加 rel="opener"
。
新标签页通过 window.opener
保持与父页面的关联,某些浏览器可能共享 sessionStorage
。现代浏览器(如Chrome)默认启用 rel="noopener"
,需显式禁用才能保持关联。所以需要设置rel="opener"
html 代码解读复制代码<a href="https://same-origin.com/page" target="_blank" rel="opener">打开新标签页a>
以上众多方法都是只有在同源的状态下且是同一个浏览器上下文中才会进行共享。
往期年度总结
- 在上海的忙碌一年,依旧充满憧憬(2024)
- 四年沿海城市,刚毕业,一年3家公司
- 七月仿佛又回到了那一年(2023年中总结)
- 一位初入职场前端仔的年度终结 <回顾2022,展望2023>
- 大学两年半的前端学习
往期文章
- 展示大量数据节点(tree),引发的一次性能排查
- ts装饰器的那点东西
- 这是你所知道的ts类型断言和类型守卫吗?
- TypeScript官网内容解读
- 经常使用ts的你,知道这些内容?
- 你有了解过原生css的scope?
- 现在比较常用的移动端调试你知道哪些?
- 众多跨标签页通信方式,你知道哪些?(二)
- 众多跨标签页通信方式,你知道哪些?
- 反调试吗?如何监听devtools的打开与关闭
- 因为原生,选择一家公司(前端如何防笔试作弊)
- 结合开发,带你熟悉package.json与tsconfig.json配置
- 如何优雅的在项目中使用echarts
- 如何优雅的做项目国际化
- 近三个月的排错,原来的憧憬消失喽
- 带你从0开始了解vue3核心(运行时)
- 带你从0开始了解vue3核心(computed, watch)
- 带你从0开始了解vue3核心(响应式)
- 3w+字的后台管理通用功能解决方案送给你
- 入职之前,狂补技术,4w字的前端技术解决方案送给你(vue3 + vite )
评论记录:
回复评论: