Day24 前端本地存储之SessionStorage

781 阅读4分钟

每日一句

It is remarkable how similar the pattern of love is to the pattern of insanity.

释义:爱与疯狂只有一线之隔。

前言

之前了解过cookie的存储方式,它是不可或缺的,是http规范的一部分。

前端如果用cookie来做数据存储,要考虑cookie有个数及大小的限制,而且不能跨域访问,每次请求一个新页面,需要带上cookie浪费带宽,且在使用上需要开发自己封装setCookie,getCookie等方法。在这种局限需求下新的存储方式应运而生就是html5中的webStorage。

webStorage除了低版本的IE,几乎所有浏览器都支持。

webStorage也是提供了浏览器存储键/值对的机制,比使用cookie更直观,其内部有两种机制:localStoragesessionStorage

这两个属性都挂载到了window上,可以很方便的通过window.localStoragewindow.sessionStorage进行访问。

image.png

sessionStorage

简单介绍

从字面上可以看出数据是保存在session中的,会话级别的存储只要浏览器(不是当前窗口)关闭数据就消失了。

一般浏览器都提供5M的存储空间。

被存储的键值对总是以 UTF-16 DOMString 的格式所存储,其使用两个字节来表示一个字符。对于对象、整数 key 值会自动转换成字符串形式。

http://example.com 与 https://example.com 的 sessionStorage 相互隔离

语法API

设置属性及值:sessionStorage.setItem('name', '张三')

获取某属性的值:sessionStorage.getItem('name')

删除某一个属性及值:sessionStorage.removeItem('name')

全部删除:sessionStorage.clear()

image.png

从浏览器控制台中可以看出返回的是一个对象,对象设置属性也可以是sessionStorage.a=1sessionStorage['a']=1几乎无差别,获取也是一样。建议使用规范写法,通过setItem或getItem方式。

另外从图中也可以看出:

  • 如果想获取长度:sessionStorage.length
  • 如果想获取第几个:sessionStorage.key(0) // 对应下标即可

调试模式如何查看sessionStorage,看图即可:

image.png

【小技巧】双击即可修改对应的值,调试灰常方便,开发者的福利。(cookie也可以哦)

加深理解

  • webStorage这么好能取代cookie吗?

不能,cookie作为客户端与服务器交互的通道,保持客户端状态,是http规范的一部分。 仅仅作为本地存储解决方案WebStorage是优于cookie。

  • 安全性的考虑

不是什么数据都适合放在 Cookie、localStorage 和 sessionStorage 中的。使用它们的时候,需要时刻注意是否有代码存在 XSS 注入的风险。因为只要打开控制台,你就随意修改它们的值,也就是说如果你的网站中有 XSS 的风险,它们就能对你的 localStorage 肆意妄为。所以千万不要用它们存储你系统中的敏感数据。

  • a标签或者使用target="_blank"打开新页面,新页面的sessionStorage丢失

sessionStorage作用范围:只存在于当前会话页面,当会话结束后,数据也随之销毁,在不同的浏览器窗口中共享。也就是存在于当前浏览器页面,页面关闭,数据也会删除。(注意:通过鼠标右键打开的新标签无法共享sessionStorage

解决方案:<a href="b.html" rel="opener">跳转</a>

只需要在a标签上加rel="opener"

原因如下:

Chrome对于a标签默认添加了noopener属性,所以通过a标签跳转,会丢失新页面的控制权,sessionStorage自然也就丢失了,我们只需要在a标签上加上 rel="opener" 就行了。

在Chrome浏览器89版本前,当前会话页面指的是当浏览器窗口没有关闭时,窗口内同域网站可以共享此数据(同源浏览器多个窗口不共享),当页面全部关闭或窗口关闭后,sessionStorage数据会被摧毁,所以你用a标签跳转还是js跳转都会共享sessionStorage。

在2021年3月初Chrome浏览器进行了批量更新,更新到89版本后,通过a标签target="_blank"跳转到新页面时sessionStorage就会丢失。Chrome这一更新可能会导致很多网站的sessionStorage丢失。

小结

  • 存储的key,value都是字符串,如果是其他格式或有特殊字符,需要通过JSON.stringify()JSON.parse()配合使用

  • cookiesessionStoragelocalStorage 异同点

特性CookielocalStoragesessionStorage
数据的生命期一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效除非被清除,否则永久保存仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小4K左右一般为5MB
与服务器端通信每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性需要程序员自己封装,源生的Cookie接口不友好源生接口可以接受,亦可再次封装来对Object和Array有更好的支持
  • sessionStorage简单封装
// 缓存读取
export const storage = {
  get(key) {
    return JSON.parse(sessionStorage.getItem(key))
  },
  set(key, value) {
    sessionStorage.setItem(key, JSON.stringify(value))
  },
  remove(key) {
    sessionStorage.removeItem(key)
  },
  clear() {
    sessionStorage.clear()
  }
}
  • 对Storage事件的监听
window.addEventlistener("storage",showStorageEvent,false);
function showStorageEvent(e){
    console.log(e.oldValue, e.newValue) // 原值,新值
}