每日一句
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
更直观,其内部有两种机制:localStorage
和sessionStorage
。
这两个属性都挂载到了window上,可以很方便的通过window.localStorage
和window.sessionStorage
进行访问。
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()
从浏览器控制台中可以看出返回的是一个对象,对象设置属性也可以是sessionStorage.a=1
或sessionStorage['a']=1
几乎无差别,获取也是一样。建议使用规范写法,通过setItem或getItem方式。
另外从图中也可以看出:
- 如果想获取长度:
sessionStorage.length
- 如果想获取第几个:
sessionStorage.key(0) // 对应下标即可
调试模式如何查看sessionStorage,看图即可:
【小技巧】双击即可修改对应的值,调试灰常方便,开发者的福利。(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()
配合使用 -
cookie
、sessionStorage
、localStorage
异同点
特性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
数据的生命期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成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) // 原值,新值
}