Web Storage 是HTML 5引入的一个重要的功能,在前端开发的过程中会经常用到,它可以在客户端本地存储数据,类似cookie,但其功能却比cookie强大的多。cookie的大小只有4Kb左右(浏览器不同,大小也不同),而web Storage的大小有5MB。LocalStorage与SessionStorage是Web Storage 的两种形式。
Web Storage是什么? |
- 存储机制
Web Storage 存储机制是一种通过 key/value键值对方式来安全地存储和使用客户端数据的方法 - 发展历程
- 作用
旨在提高网站访问效率。通过减少与服务器端进行请求传输,降低宽带资源占用,将某些可复用性强(偏静态)的数据保存在客户端,直接读取客户端保存的数据。
localStorage、sessionStorage与cookie的异同 |
特性 | Cookie | localStorage | sessionStorage |
数据的生命期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 除非被清除(清除浏览器缓存或者removeItem),否则永久保存 | 仅在当前会话下有效,关闭页面或浏览器后被清除 |
数据量限制 | 每个域名下可创建的Cookie数量有限制 | 数据条数无限制 | |
存放数据大小 | 4K | 约5M | |
与服务器端通信 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 |
localStorage的局限 |
1、各浏览器的localStorage大小不统一,并且IE只在IE8以上版本才支持localStorage。
2、localStorage只能存储字符串,任何格式的数据在存储的时候都会被自动转为字符串,所以读取的时候,需要进行类型的转换。
3、localStorage本质上是对字符串的存储和读取,存储数据会消耗浏览器的内存空间,存储数据多的情况下,会影响浏览器响应效率。
4、localStorage在浏览器的隐私模式下是不可读取的。
5、localStorage不能被爬虫抓取到。
应用场景 |
有了对上面这些差别的直观理解,我们就可以讨论三者的应用场景了。
因为考虑到每个 HTTP 请求都会带着 Cookie 的信息,所以 Cookie 当然是能精简就精简啦,比较常用的一个应用场景就是判断用户是否登录。针对登录过的用户,服务器端会在他登录时往 Cookie 中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。曾经还使用 Cookie 来保存用户在电商网站的购物车信息,如今可使用 localStorage替代。
而另一方面 localStorage 接替了 Cookie 管理购物车的工作,同时也能胜任其他一些工作。比如HTML5游戏通常会产生一些本地数据,localStorage 也是非常适用的。如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表单页面拆分成多个子页面,然后按步骤引导用户填写。这时候 sessionStorage 的作用就发挥出来了。
安全性的考虑 |
需要注意的是,不是什么数据都适合放在 Cookie、localStorage 和 sessionStorage 中的。使用它们的时候,需要时刻注意是否有代码存在 XSS 注入的风险。因为只要打开控制台,你就随意修改它们的值,也就是说如果你的网站中有 XSS 的风险,它们就能对你的 localStorage 肆意妄为。所以千万不要用它们存储你系统中的敏感数据。
sessionStorage与localStorage的作用域 |
这里的作用域指的是:如何隔离开不同页面之间的localStorage(总不能在百度的页面上能读到腾讯的localStorage吧)
- localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据。
- sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口下。怎么理解这个同一窗口呢?比如在A页面中设置了sessionStorage,只有通过A页面中打开的其他同网站内的其他页面才可以读取到这个值(当然还有限制,详见下文opener属性)。至于localStorage的话,假如在某服务器的某端口下部署了多个网站,各个网站之间是可以读取到这个值的(可使用Hbulider简单测试下便知)。
注意
1. localStorage
localStorage的生命周期是永久性的。假若使用localStorage存储数据,即使关闭浏览器,也不会让数据消失,除非主动的去删除数据(清除浏览器缓存或者removeItem)
2. sessionStorage
sessionStorage 的生命周期是在浏览器关闭前。也就是说,在整个浏览器未关闭前,其数据一直都是存在的。其基本的判断和使用方法和localStorage的使用是一致的。有几点需要注意的:
<1>页面刷新不会删除数据
<2> 直接通过<a href='xx.html'>
打开页面无法获取window.opener
属性
<3>在新打开的页面(直接网址打开)传递的sessionStorage具有隔离性
<4>使用window.open打开页面和改变localtion.href方式都可以获取到sessionStorage内部的数据(通过window.open
和localtion.href
打开的页面依然可以获得window.opener
属性)
rel ="noreferrer" 标记在单击链接时隐藏引用者信息 (目前已失效)rel ="noopener"
在新标签中打开链接时不会引入开启者的信息(目前已失效)
Storage接口 |
Storage 接口用于脚本在浏览器保存数据。
window.sessionStorage
和window.localStorage
属性返回的数据类型都是Storage,支持HTML5的浏览器都实现了Storage接口,因此这两个属性都可以返回一个Storage对象。
Storage接口只有一个属性
-
Storage.length
返回存储在Storage对象内的 key/value 对的个数。
Storage接口提供五个方法
Storage.key(n
) 返回存储在Storage对象内的第 n 条数据的 key 。Storage.getItem(key)
返回指定key的value。Storage.setItem(key,value)
向Storage对象内添加或更新 key/value。Storage.removeItem(key)
从Storage对象内删除指定 key/value。Storage.clear()
从Storage对象内删除所有 key/value。
localStorage的用法 |
localStorage和sessionStorage方法和属性用起来是一样的,两者不同之处在于生命周期,以下用localStorage进行讲解。
localStorage的浏览器支持情况:
localStorage的写入和读取(三种方式) |
<script>
localStorage.name='Yasuo'
localStorage.setItem('age',24)
localStorage['game']='lol'
console.log(localStorage.name)
console.log(localStorage['age'])
console.log(localStorage.getItem("game"))
</script>
localStorage只支持string类型的存储,所以我们存进去的值都变成了string类型。
而我们通常使用到的是json字符串,我们可以 JSON.stringify()
方法将js对象转为json字符串,之后我们还可以使用 JSON.parse()
方法将json字符串转为json对象
localStorage.name='Yasuo'
localStorage.setItem('age',24)
localStorage['game']='lol'
console.log(localStorage)
console.log(JSON.stringify(localStorage))
console.log(JSON.parse(JSON.stringify(localStorage)))
可见,localStorage返回的是Storage对象类型
虽然有多种方法进行存取,但是官方推荐getItem\setItem,因为这种写法更符合面向对象编程。
localStorage的删除 |
- 删除指定属性
localStorage.removeItem("name")
- 清空整个localStorage对象
localStorage.clear()
localStorage的获取键名 |
<script>
localStorage.name='Yasuo'
localStorage.setItem('age',24)
localStorage['game']='lol'
console.log(localStorage.key(0),localStorage.key(1),localStorage.key(2))
</script>
控制态输出的是:name age game
localStorage.key(0) 填入的是key的索引值,从0开始,根据localStorage写入值的顺序递增