H5-新增API
本地存储
随着互联网的快速发展,基于网页的应用越来越普遍,
同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,
HTML5规范提出了相关解决方案。
主流的浏览器上都在window对象上定义了两个属性:localStorage和sessionStorage。这两个属性都代表同一个Storage对象,该对象是一个持久化关联数组,数组使用字符串来索引,存储的值也都是字符串形式的。Storage对象在使用上和一般的JS对象没什么区别:设置对象的属性为字符串值,随后浏览器会将该值存储起来。
- 特性
- 设置、读取方便
- 容量较大,sessionStorage约5M、localStorage约20M
- 只能存储字符串,可以将对象JSON.stringify() 编码后存储
- window.localStorage
- 永久生效,除非手动删除(服务器方式访问然后清除缓存)
- 可以多窗口(页面)共享
- window.sessionStorage
- 生命周期为关闭浏览器窗口
- 在同一个窗口(页面)下数据可以共享
- 方法
- setItem(key, value) 设置存储内容
- getItem(key) 读取存储内容
- removeItem(key) 删除键值为key的存储内容
- clear() 清空所有存储内容
存储有效期和作用域
localStorage和sessionStorage的区别在于存储的有效期和作用域的不同。
localStorage
通过localStorage存储的数据是永久性的,除非web应用刻意删除存储的数据,或者用户通过设置浏览器配置来删除,数据将一直保留在用户的电脑上,永不过期。localStorage的作用域是限定在文档源级别的。文档源是通过协议、主机名以及端口三者来确定的,因此,下面每个URL都拥有不同的文档源:
http://www.example.com // 协议:http;主机名:www.example.com
https://www.example.com // 不同协议
http://www.baidu.com // 不同主机名
http://www.example.com:8000 // 不同端口
- 所谓的端口,就好像是门牌号一样,客户端可以通过ip地址找到对应的服务器端,但是服务器端是有很多端口的,每个应用程序对应一个端口号,通过类似门牌号的端口号,客户端才能真正的访问到该服务器。为了对端口进行区分,将每个端口进行了编号,这就是端口号。
- 同源的文档(协议、主机名、端口号)间共享相同的localStorage数据。它们可以互相读取对方的数据,甚至可以覆盖对方的数据。但是,非同源的文档间互相都不能读取或者覆盖对方的数据。
- 需要注意的是localStorage的作用域也受浏览器供应商限制。如果你使用火狐浏览器访问站点,那么下次用另一个浏览器(比如,Chrome)再次访问的时候,那么本次是无法获取上次存储的数据。
sessionStorage
- 通过sessionStorage存储的数据有效期和存储数据的脚本所在的最顶层的窗口或者是浏览器标签页是一样的。一旦窗口或者标签页被永久关闭了,那么所有通过sessionStorage存储的数据也都被删除了。(当时要注意的是,现代浏览器已经具备了重新打开最近关闭的标签页随后恢复上一次浏览的会话功能,因此,这些标签页以及与之相关的sessionStorage的有效期可能会更加长些)。
- 与localStorage一样,sessionStorge的作用域也是限定在文档源中,因此
- 非同源文档间都是无法共享sessionStorage的。
- sessionStorage的作用域还被限定在窗口中。如果同源的文档渲染在不同的浏览器标签页中,那么它们互相之间拥有的是各自的sessionStorage数据,无法共享;
- 一个标签页中的脚本是无法读取或者覆盖由另一个标签页脚本写入的数据,哪怕这两个标签页渲染的是同一个页面,运行的是同一个脚本也不行。
- 要注意的是,这里提高到的基于窗口作用域的sessionStorage指的窗口只是顶级窗口。如果一个浏览器标签页包含两个<iframe>元素,它们所包含的文档是同源的,那么这两者之间是可以共享sessionStorage的。
本地存储的方法
调用setItem(key, value)方法将对应的名字和值传递进去,可以实现数据存储。
localStorage.setItem('name', '张三');
调用getItem(key)方法,将名字传递进去,可以获得对应的值。
localStorage.getItem('name'); // '张三'
调用removeItem(key)方法,将名字传递进去,可以删除对应的数据。
localStorage.removeItem('name');
调用clear()方法(不需要参数),可以删除所有存储的数据。
localStorage.clear();
最后,使用length属性和key(index)方法,传入0至length-1之间的数字,可以遍历所有存储数据的名字。
for(var i = 0; i < localStorage.length; i++) { //length表示所有键值对的总数
var name = localStorage.key(i); // 获取第i对的名字
var value = localStorage.getItem(name); // 获取name对应的值
}
存储事件
无论什么时候存储在localStorage或sessionStorage的数据发生改变,浏览器都会在其他对该数据可见的窗口对象上触发存储事件(但是,在对数据进行改变的窗口对象上是不会触发的)。如果浏览器有两个标签页都打开了来自同源的页面,其中一个页面在localStorage上存储了数据,那么另一个标签页就会接收到一个存储事件。要记住的是sessionStorage的作用域是限制在顶层窗口的,因此对sessionStorage的改变只有当有相牵连的窗口的时候才会触发存储事件。还需要注意的是,只有当存储数据真正发生改变时才会触发存储事件。像给已经存在的存储项设置一个一模一样的值,抑或是删除一个本来就不存在的存储项都是不会触发存储事件的。
为存储事件注册处理程序可以使用addEventListener()方法。在绝大多数浏览器中,还可以使用给window对象设置onstorage属性的方式。
注意点:onstorage当前页面不触发:
- 当前页面不同窗口触发。
- 另外的监听页面触发。
与存储事件相关的事件对象有5个非常重要的属性:
- key : 修改或删除的key值,如果调用clear()时,该属性值为null
- newValue: 新设置的值,如果调用removeItem()时,该属性值为null
- oldValue : 调用改变前的value值;添加新项时,该属性值为null
- storageArea : 当前的storage对象
- url : 触发该存储变化脚本所在文档的URL(也就是说哪个页面修改的数据)