面试官:你确定多窗口之间sessionStorage不能共享状态吗?

更新日期: 2023-02-10阅读: 499标签: 缓存
作者:不要秃头啊
链接:https://juejin.cn/post/7076767687828832286


一、背景

面试官:说一说localStorage和sessionStorage区别呗?

我:巴拉巴拉。。。(这不是小case嘛,面经都背烂了)

面试官:那同域下多窗口间localStorage能共享吗?

我:可以呀,如果页面中出现了串数据的话,很大概率就是localStorage共享导致的呢。

面试官:localStorage既然可以,那sessionStorage在多窗口之间能共享状态吗?

我:当然不行,每一个窗口之间sessionStorage都是独立的,相互不影响,窗口关闭浏览器就自动销毁了!(斩钉截铁,认真脸)

面试官:你确定多窗口之间sessionStorage不能共享状态吗???

我:这个。。。。不太确定。。。。待我去查查资料再来。。。


由此引出我们今天的主题:sessionStorage在同域下的多窗口之间能共享状态吗?


二、查阅文档

根据MDN的说法:

sessionStorage 属性允许你访问一个,对应当前源的 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。

  1. 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
  2. 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文, 这点和 session cookies 的运行方式不同。
  3. 打开多个相同的 URL 的 Tabs 页面,会创建各自的 sessionStorage。
  4. 关闭对应浏览器标签或窗口,会清除对应的 sessionStorage。

对于上面的说法,第134点相信都是符合大家认知的,那第二点是啥意思呢?

笔者为了搞懂第二点,接着继续查阅文档。。。

经过一系列的学习 (百度) 之后,笔者发现如果从本页面以新开页签的方式打开一个同域下的新页面,新开的页面会和之前的页面 ‘共享’ sessionStorage。

举个实际一点的例子:现有页面A,在页面A中执行

window.sessionStorage.setItem("pageA_1","123")

在页面中有个button按钮,点击按钮触发 window.open("同源页面"),现得到新开的页面B,在B中执行

window.sessionStorage.getItem("pageA_1") //拿到的结果是 "123"

这里的B页面居然是能拿到值的!!!!

现在我终于能对面试官说:多窗口之间sessionStorage真的可以共享状态!!

此时面试官:再给你一次机会,好好组织一下语言

三、真的是这样吗?

哎,等等,如果真的能共享数据,那 sessionStorage 不是也会出现串数据的情况吗,我怎么记得平时并不会。。。

接下来我们继续测试,在页面A中继续执行

window.sessionStorage.setItem("pageA_1","456") (之前的pageA_1设置的值是 ‘123’ )
window.sessionStorage.setItem("pageA_2","789")

在页面B中再次尝试获取:

window.sessionStorage.getItem("pageA_1") //拿到的结果还是 "123" !!!
window.sessionStorage.getItem("pageA_2") //拿到的结果是 null !!!

what??? 怎么回事?怎么现在又不‘共享’了呢?

我们现在再次回去理解一下MDN的说法:在该标签或窗口打开一个新页面时会复制顶级浏览会话的上下文作为新会话的上下文

哦~ 原来如此~ 原来只有在本页面中以新页签或窗口打开的同源页面会‘临时共享’之前页面的sessionStorage。

而且共享这个词似乎也并不怎么准确,准确来说应该叫复制更加专业!

现在我终于能再次对面试官说:多窗口之间sessionStorage不可以共享状态!!!但是在某些特定场景下新开的页面会复制之前页面的sessionStorage!!

此时面试官:嗯~小伙子看来理解的还不错嘛

四、总结

其实不仅window.open("同源页面")这种方式新开的页面会复制之前的sessionStorage,通过a标签新开的页面同样也会,原理相同,在这就不赘述了。

通过a标签新开的页面同样也会,原理相同。

而Chrome 89的版本,Stop cloning sessionStorage for windows opened with noopener,而a标签_blank默认 rel="noopener" ,所以a标签需要加入rel=“opener” 而才能像window.open("同源页面")这种方式新开的页面会复制之前的sessionStorage

<a href="http://..." target="_blank" rel="opener">Link</a>


五、其他

这里可能有部分同学要问了:如果我就是不想要这种复制的效果怎么办呢?

这里笔者认为优雅一点的方式是先新建一个空白页面窗口,再将url设置到窗口中的地址栏中去。

链接: https://www.fly63.com/article/detial/12361

浏览器缓存_HTTP强缓存和协商缓存

浏览器缓存主要分为强强缓存(也称本地缓存)和协商缓存(也称弱缓存),强缓存是利用http头中的Expires和Cache-Control两个字段来控制的,用来表示资源的缓存时间。协商缓存就是由服务器来确定缓存资源是否可用.

angularjs 缓存详解

一个缓存就是一个组件,它可以透明地存储数据,以便未来可以更快地服务于请求。缓存能够服务的请求越多,整体系统性能就提升得越多。

浏览器缓存问题原理以及解决方案

浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中,为什么使用缓存:减少网络带宽消耗,降低服务器压力,减少网络延迟,加快页面打开速度

Web缓存相关知识整理

一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面。用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了下Web缓存的知识

使用缓存加速之后的网站访问过程变化

在描述CDN的实现原理之前,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别,用户访问未使用CDN缓存网站的过程为:用户向浏览器提供要访问的域名;

html页面清除缓存

页面打开时,由于缓存的存在,刚刚更新的数据有时无法在页面得到刷新,当这个页面作为模式窗口被打开时问题更为明显, 如何将缓存清掉?

HTTP之缓存 Cache-Control

通过在Response Header设置Cache-Control head 信息可以控制浏览器的缓存行为。我们先来看一下Cache-Control可以设置哪些值:缓存头Cache-Control只能在服务端设置,在客户端是由浏览器设置的,自己不能修改它的值。

工程化_前端静态资源缓存策略

增量更新是目前大部分团队采用的缓存更新方案,能让用户在无感知的情况获取最新内容。具体实现方式通常是(一般我们通过构建工具来实现,比如webpack):

前端静态资源自动化处理版本号防缓存

浏览器会默认缓存网站的静态资源文件,如:js文件、css文件、图片等。缓存带来网站性能提升的同时也带来了一些困扰,最常见的问题就是不能及时更新静态资源,造成新版本发布时用户无法及时看到新版本的变化,严重影响了用户体验。

vue后台管理系统解决keep-alive页面路由参数变化时缓存问题

一个后台管理系统,一个列表页A路由配置需要缓存,另一个页面B里面有多个跳转到A路由的链接。问题描述:首先访问/A?id=1页面,然后到B页面再点击访问A?id=2的页面,发现由于页面A设置了缓存,数据还是id=1的数据,并没有更新。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!