sessionStorage什么时候失效

最近在调试程序的时候无意间看到 cookie 的过期时间是 session,这个 session 表示的是什么时候过期?牵扯出来另一个存储方案 sessionStorage 存储的数据又是什么时候过期呢?

在查找相关资料的时候总会看到会话结束的时候 cookie 会被清除,当然 sessionStorage 内的数据也会在会话结束的时候被清除。

问题又来了会话是什么?会话什么时候会结束?

暂时抛开这些问题,看看 sessionStorage 是怎么使用,和之前的持久化存储方案 cookie 有什么不同。

Storage

Storage 是 Web Storage API 的接口,localStorage 和 sessionStorage 都实现了这个接口,所以这两个对象都有这个接口定义的属性和方法。

  • Storage.length:只读 存储的数据项数量

  • Storage.key(n: number):返回存储的第 n 个键名

  • Storage.getItem(key: string):返回 key 对应的值

  • Storage.setItem(key: string, value: string):存储键和值,如果存在则更新

  • Storage.clear():清空存储的所有数据

Storage 和 cookies

cookie localStorage sessionStorage
随 HTTP 发送
最大数据量 4K 5M 5M
失效时机 自己定义 或 随着会话断开失效 不清除不失效 随着会话断开失效
跨域限制

下面是 MDN 对 sessionStorage 的描述:

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

页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。

在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这点和 session cookies 的运行方式不同。

打开多个相同的 URL 的 Tabs 页面,会创建各自的 sessionStorage。

关闭对应浏览器窗口(Window)/ tab,会清除对应的 sessionStorage。

上面的内容引用自MDN Window.sessionStorage

对于以上的引用内容有如下问题:

什么是会话?

我理解会话是两个实体之间的交流,交流是一个过程,无论从时间还是从内容都会表现成一个过程,一段时间。例如:从输入账户密码进入系统到退出系统就是一次会话的完成。TCP 的三次握手也创建了一次会话,TCP 四次挥手关闭连接则关闭了会话。

重新加载或恢复页面,什么是恢复页面?

恢复页面就是浏览器窗口/tab 手动关闭或者意外关闭都是可以恢复的,恢复之后这个页面的会话也会随之恢复。前提是浏览器程序没有被退出,如果程序被退出了无论是手动退出还是意外退出 session storage 和 session cookies 都会被清除。

在新标签或窗口打开页面,是在哪里打开的新窗口或页面?复制顶级浏览会话,之后两个会话就没有联系了吗?

这里的打开新的标签/窗口指的是在当前页面触发的动作导致新窗口/tab 的打开。复制而来的会话(session storage)和之前的会话没有联系。

和 session cookies 的运作方式不同,session cookies 的运作方式是什么?

session cookies 的运作方式不是复制,不同窗口/tab 同一域操作的 cookies 是同一个。

加载别的页面是否算是会话结束?

不算会话结束,因为当前 tab 再次加载对应的 url 的时候还是可以访问到对应的 sessionStorage。

为了解答上面的问题,我的尝试如下:

  1. 在域 http://www.xx.com:80 下写入数据sessionStorage.setItem('a', 1)

  2. 关闭当前 tab/窗口(保持浏览器程序没有退出)

  3. 历史记录 -> 最近关闭的 tab -> 刚才关闭的 tab

  4. sessionStorage.getItem('a')可以得到"1"

表明恢复的标签和之前的标签共享一个会话,因为它们是同一个标签

  1. 当前标签加载其它域名例如 http://jd.com

  2. 在回来 http://www.xx.com:80 这时候可以通过 sessionStorage.getItem('a')得到值"1"

表明同一个标签同一个域会共享会话

  1. 在当前页面通过链接 打开(注意这里的ref属性,一定要加上,缺省则不会有效)

  2. 在新开的 tab 下sessionStorage.getItem('a')可以得到得到值"1"

  3. 在新开的 tab 下sessionStorage.setItem('a', 2)

  4. 在原来的 tab 下sessionStorage.getItem('a')得到的还是 1

表明从当前域打开新的 tab/窗口会复制当前的会话作为新开页面的会话,因为是复制出来的,两个会话之间没有关联

  1. 关闭浏览器程序

  2. 再次打开浏览器,并且恢复 tab(不是新开 tab 打开同域页面)

  3. sessionStorage.getItem('a')得到的是 null 而不是"1"

表明关闭浏览器程序会结束会话

session cookies的失效

和 sessionStorage 的尝试一致,对于 cookie 的过期时间是 session 也做了如上尝试,得出的结论如下:

在浏览器关闭的情况下 session cookies 才会被清除,只是关闭相关 tab session cookies 还是存在,在此打开对应域的链接还是会看到相应cookies。

补充

  1. 对于rel="noopener"的a标签打开的链接不会复制opener的sessionStorage,
    参考Feature: Stop cloning sessionStorage for windows opened with noopener。
  2. 近期chrome浏览器修改了a标签rel属性缺省的默认值为noopener,参考Feature: Anchor target=_blank implies rel=noopener by default。
  3. 关于a标签的rel属性可以参数考HTML attribute: rel

参考

MDN Window.sessionStorage

MDN Storage

HTTP 会话原理解释与应用

sessionStorage 你可能会忽略的细节

实际中使用 Javascript 中 sessionStorage 的注意事项

你可能感兴趣的:(javascript,sessionstorage,storage,localstorage,cookie)