Web Storage 最早是在Web 超文本应用技术工作组(WHAT-WG)的Web 应用1.0 规范中描述的。
这个规范的最初的工作最终成为了HTML5 的一部分。Web Storage 的目的是克服由cookie 带来的一些限制,当数据需要被严格控制在客户端上时,无须持续地将数据发回服务器。Web Storage 的两个主要目标是:

  • 提供一种在cookie 之外存储会话数据的途径;
  • 提供一种存储大量可以跨会话存在的数据的机制。

最初的Web Storage 规范包含了两种对象的定义:sessionStorage 和globalStorage。这两个对象在支持的浏览器中都是以windows 对象属性的形式存在的,支持这两个属性的浏览器包括IE8+、Firefox 3.5+、Chrome 4+和Opera 10.5+。
Firefox 2 和3 基于早期规范的内容部分实现了Web Storage,当时只实现了globalStorage,没有实现localStorage。

1. Storage 类型

Storage 类型提供最大的存储空间(因浏览器而异)来存储名值对儿。Storage 的实例与其他对象类似,有如下方法。

  • clear(): 删除所有值;Firefox 中没有实现 。
  • getItem(name):根据指定的名字name 获取对应的值。
  • key(index):获得index 位置处的值的名字。
  • removeItem(name):删除由name 指定的名值对儿。
  • setItem(name, value):为指定的name 设置一个对应的值。

其中,getItem()、removeItem()和setItem()方法可以直接调用,也可通过Storage 对象间接调用。因为每个项目都是作为属性存储在该对象上的,所以可以通过点语法或者方括号语法访问属性来读取值,设置也一样,或者通过delete 操作符进行删除。不过,我们还建议读者使用方法而不是属性来访问数据,以免某个键会意外重写该对象上已经存在的成员。
还可以使用length 属性来判断有多少名值对儿存放在Storage 对象中。但无法判断对象中所有数据的大小,不过IE8 提供了一个remainingSpace 属性,用于获取还可以使用的存储空间的字节数。Storage 类型只能存储字符串。非字符串的数据在存储之前会被转换成字符串。

2. sessionStorage 对象

sessionStorage 对象存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭。这个对象就像会话cookie,也会在浏览器关闭后消失。存储在sessionStorage 中的数据可以跨越页面刷新而存在,同时如果浏览器支持,浏览器崩溃并重启之后依然可用(Firefox 和WebKit 都支持,IE 则不行)。
因为seesionStorage 对象绑定于某个服务器会话,所以当文件在本地运行的时候是不可用的。存储在sessionStorage 中的数据只能由最初给对象存储数据的页面访问到,所以对多页面应用有限制。由于sessionStorage 对象其实是Storage 的一个实例,所以可以使用setItem()或者直接设置新的属性来存储数据。下面是这两种方法的例子。

//使用方法存储数据
sessionStorage.setItem("name", "Nicholas");
//使用属性存储数据
sessionStorage.book = "Professional JavaScript";

不同浏览器写入数据方面略有不同。Firefox 和WebKit 实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE 的实现则是异步写入数据,所以在设置数据和将数据实际写入磁盘之间可能有一些延迟。对于少量数据而言,这个差异是可以忽略的。对于大量数据,你会发现IE 要比其他浏览器更快地恢复执行,因为它会跳过实际的磁盘写入过程。
在IE8 中可以强制把数据写入磁盘:在设置新数据之前使用begin()方法,并且在所有设置完成之后调用commit()方法。看以下例子。

//只适用于IE8
sessionStorage.begin();
sessionStorage.name = "Nicholas";
sessionStorage.book = "Professional JavaScript";
sessionStorage.commit();

这段代码确保了name 和book 的值在调用commit()之后立刻被写入磁盘。调用begin()是为了确保在这段代码执行的时候不会发生其他磁盘写入操作。对于少量数据而言,这个过程不是必需的;不过,对于大量数据(如文档之类的)可能就要考虑这种事务形式的方法了。sessionStorage 中有数据时,可以使用getItem()或者通过直接访问属性名来获取数据。两种方法的例子如下。

//使用方法读取数据
var name = sessionStorage.getItem("name");
//使用属性读取数据
var book = sessionStorage.book;

还可以通过结合length 属性和key()方法来迭代sessionStorage 中的值,如下所示。

for (var i = 0,
len = sessionStorage.length; i < len; i++) {var key = sessionStorage.key(i);var value = sessionStorage.getItem(key);alert(key + "=" + value);
}

它是这样遍历sessionStorage 中的名值对儿的:首先通过key()方法获取指定位置上的名字,然后再通过getItem()找出对应该名字的值。还可以使用for-in 循环来迭代sessionStorage 中的值:

for (var key in sessionStorage) {var value = sessionStorage.getItem(key);alert(key + "=" + value);
}

每次经过循环的时候,key 被设置为sessionStorage 中下一个名字,此时不会返回任何内置方法或length 属性。要从sessionStorage 中删除数据,可以使用delete 操作符删除对象属性,也可调用removeItem()方法。以下是这些方法的例子。

//使用delete 删除一个值——在WebKit 中无效
delete sessionStorage.name;
//使用方法删除一个值
sessionStorage.removeItem("book");

运行一下
在撰写本书时,delete 操作符在WebKit 中无法删除数据,removeItem()则可以在各种支持的浏览器中正确运行。sessionStorage 对象应该主要用于仅针对会话的小段数据的存储。如果需要跨越会话存储数据,那么globalStorage 或者localStorage 更为合适。

3. globalStorage 对象

Firefox 2 中实现了globalStorage 对象。作为最初的Web Storage 规范的一部分,这个对象的目的是跨越会话存储数据,但有特定的访问限制。要使用globalStorage,首先要指定哪些域可以访问该数据。可以通过方括号标记使用属性来实现,如以下例子所示。

//保存数据
globalStorage["wrox.com"].name = "Nicholas";
//获取数据
var name = globalStorage["wrox.com"].name;

在这里,访问的是针对域名wrox.com 的存储空间。globalStorage 对象不是Storage 的实例,而具体的globalStorage["wrox.com"]才是。这个存储空间对于wrox.com 及其所有子域都是可以访问的。可以像下面这样指定子域名。

//保存数据
globalStorage["www.wrox.com"].name = "Nicholas";
//获取数据
var name = globalStorage["www.wrox.com"].name;

这里所指定的存储空间只能由来自www.wrox.com 的页面访问,其他子域名都不行。
某些浏览器允许更加宽泛的访问限制,比如只根据顶级域名进行限制或者允许全局访问,如下面例子所示。

//存储数据,任何人都可以访问——不要这样做!
globalStorage[""].name = "Nicholas";
//存储数据,可以让任何以.net 结尾的域名访问——不要这样做!
globalStorage["net"].name = "Nicholas";

虽然这些也支持,但是还是要避免使用这种可宽泛访问的数据存储,以防止出现潜在的安全问题。
考虑到安全问题,这些功能在未来可能会被删除或者是被更严格地限制,所以不应依赖于这类功能。当使用globalStorage 的时候一定要指定一个域名。
对globalStorage 空间的访问,是依据发起请求的页面的域名、协议和端口来限制的。例如,如果使用HTTPS 协议在wrox.com 中存储了数据,那么通过HTTP 访问的wrox.com 的页面就不能访问该数据。同样,通过80 端口访问的页面则无法与同一个域同样协议但通过8080 端口访问的页面共享数据。这类似于Ajax 请求的同源策略。globalStorage 的每个属性都是Storage 的实例。因此,可以像如下代码中这样使用。

globalStorage["www.wrox.com"].name = "Nicholas";
globalStorage["www.wrox.com"].book = "Professional JavaScript";
globalStorage["www.wrox.com"].removeItem("name");
var book = globalStorage["www.wrox.com"].getItem("book");

如果你事先不能确定域名,那么使用location.host 作为属性名比较安全。例如:

globalStorage[location.host].name = "Nicholas";
var book = globalStorage[location.host].getItem("book");

运行一下
如果不使用removeItem() 或者delete 删除, 或者用户未清除浏览器缓存, 存储在globalStorage 属性中的数据会一直保留在磁盘上。这让globalStorage 非常适合在客户端存储文档或者长期保存用户偏好设置。

4. localStorage 对象

localStorage 对象在修订过的HTML 5 规范中作为持久保存客户端数据的方案取代了globalStorage。与globalStorage 不同,不能给localStorage 指定任何访问规则;规则事先就设定好了。要访问同一个localStorage 对象,页面必须来自同一个域名(子域名无效),使用同一种协议,在同一个端口上。这相当于globalStorage[location.host]。
由于localStorage 是Storage 的实例,所以可以像使用sessionStorage 一样来使用它。下面是一些例子。

//使用方法存储数据
localStorage.setItem("name", "Nicholas");
//使用属性存储数据
localStorage.book = "Professional JavaScript";
//使用方法读取数据
var name = localStorage.getItem("name");
//使用属性读取数据
var book = localStorage.book;

运行一下
存储在localStorage 中的数据和存储在globalStorage 中的数据一样,都遵循相同的规则:数据保留到通过JavaScript 删除或者是用户清除浏览器缓存。为了兼容只支持globalStorage 的浏览器,可以使用以下函数。

function getLocalStorage() {if (typeof localStorage == "object") {return localStorage;} else if (typeof globalStorage == "object") {return globalStorage[location.host];} else {throw new Error("Local storage not available.");}
}

然后,像下面这样调用一次这个函数,就可以正常地读写数据了。

var storage = getLocalStorage();

运行一下
在确定了使用哪个Storage 对象之后,就能在所有支持Web Storage 的浏览器中使用相同的存取规则操作数据了。

5. storage 事件

对Storage 对象进行任何修改,都会在文档上触发storage 事件。当通过属性或setItem()方法保存数据,使用delete 操作符或removeItem()删除数据,或者调用clear()方法时,都会发生该事件。这个事件的event 对象有以下属性。

  • domain:发生变化的存储空间的域名。
  • key:设置或者删除的键名。
  • newValue:如果是设置值,则是新值;如果是删除键,则是null。
  • oldValue:键被更改之前的值。

在这四个属性中,IE8 和Firefox 只实现了domain 属性。在撰写本书的时候,WebKit 尚不支持storage 事件:以下代码展示了如何侦听storage 事件:

EventUtil.addHandler(document, "storage", function(event){alert("Storage changed for " + event.domain);
});

运行一下
无论对sessionStorage、globalStorage 还是localStorage 进行操作,都会触发storage事件,但不作区分。

6. 限制

与其他客户端数据存储方案类似,Web Storage 同样也有限制。这些限制因浏览器而异。一般来说,对存储空间大小的限制都是以每个来源(协议、域和端口)为单位的。换句话说,每个来源都有固定大小的空间用于保存自己的数据。考虑到这个限制,就要注意分析和控制每个来源中有多少页面需要保存数据。
对于localStorage 而言,大多数桌面浏览器会设置每个来源5MB 的限制。Chrome 和Safari 对每个来源的限制是2.5MB。而iOS 版Safari 和Android 版WebKit 的限制也是2.5MB。
对sessionStorage 的限制也是因浏览器而异。有的浏览器对sessionStorage 的大小没有限制,但Chrome、Safari、iOS 版Safari 和Android 版WebKit 都有限制,也都是2.5MB。IE8+和Opera 对sessionStorage 的限制是5MB。

有关Web Storage 的限制,请参考http://dev-test.nemikor.com/web-storage/support-test/。

下载离线版教程:http://www.shouce.ren/api/view/a/15218

转载于:https://www.cnblogs.com/itzhoubao/p/6843926.html

23.3.3 Web存储机制【JavaScript高级程序设计第三版】相关推荐

  1. JavaScript高级程序设计第三版.CHM【带实例】

    从驱动全球商业.贸易及管理领域不计其数的复杂应用程序的角度来看,说 JavaScript 已经成为当今世界上最流行的编程语言一点儿都不为过. JavaScript 是一种非常松散的面向对象语言,也是 ...

  2. javascript高级程序设计 第三版

    网盘地址 提取码:vh81 笔记 第二章 2.1script标签 <script>元素属性:async.charset.defer.language.src.type async和defe ...

  3. JavaScript高级程序设计第三版 第3章 基本概念

    第3章 基本概念 3.1 语法 3.1.1 区分大小写 3.1.2 标识符 3.1.3 注释 3.1.4 严格模式 3.1.5 语句 3.2 关键字和保留字 3.3 变量 3.4 数据类型 3.4.1 ...

  4. 10.1.2 Document类型【JavaScript高级程序设计第三版】

    JavaScript 通过Document 类型表示文档.在浏览器中,document 对象是HTMLDocument(继承自Document 类型)的一个实例,表示整个HTML 页面.而且,docu ...

  5. 13.4.3 鼠标与滚轮事件【JavaScript高级程序设计第三版】

    鼠标事件是Web 开发中最常用的一类事件,毕竟鼠标还是最主要的定位设备.DOM3 级事件中定义了9 个鼠标事件,简介如下. click:在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发.这 ...

  6. DOM2和DOM3——JavaScript高级程序设计第三版第12章知识总结

    DOM2和DOM3

  7. JavaScript高级程序设计第四版学习--第二十四章

    title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...

  8. JavaScript高级程序设计[第3版]

    JavaScript高级程序设计[第3版] package xyz.huning.toolkit.pdf;import java.io.FileOutputStream; import java.io ...

  9. JavaScript高级程序设计 第4版----String

    JavaScript高级程序设计 第4版----String 文章目录 JavaScript高级程序设计 第4版----String 1.JavaScript 字符 2.字符串操作方法 1.conca ...

  10. Js高级程序设计第三版学习(十二章)

                                  Js高级程序设计第三版学习(十二章) 第十二章 DOM2和DOM3   1.样式: 访问样式属性 任何支持style特性的HTML元素都有一 ...

最新文章

  1. JavaScript typeof() 这个函数是干什么用的?有几个参数,每个参数代表什么?
  2. php 结构体_【开发规范】PHP编码开发规范下篇:PSR-2编码风格规范
  3. win10无法新建文件夹怎么办 win10右键新建菜单设置方法
  4. python的计算_python计算smoothed PSSM(二)
  5. 检测X光图像中Covid-19
  6. 电脑usb蓝牙的使用
  7. How long is the way to the Architect?
  8. 团队协作管理-任务追踪管理
  9. 局域网共享文件夹/共享文件夹无法访问解决办法
  10. 《欲望之源》(《MEAN GENES》)
  11. 广达服务器进系统重启,广达 服务器 远程开机
  12. 【学术前沿趋势分析 】
  13. 每日一犬 · 布鲁克浣熊猎犬
  14. Java POI导出word文件及生成表格
  15. 【控制control】机械臂运动学、动力学模型
  16. STM32 固件库外设 GPIO 讲解(关于 GPIO 寄存器讲解)
  17. 第三十五章 SQL函数 CURRENT_DATE
  18. 爬虫Python入门好学吗
  19. 往前推算时间算法示例-java
  20. HTML 访问本地 Markdown 文件

热门文章

  1. 功能1 -- 顶部导航栏和返回顶部效果
  2. iOS黑魔法 - Method Swizzling
  3. Library弱依赖打包
  4. 容器就业市场持续增长,5条建议让您快速掌握Docker技能
  5. Linux下Apache、PHP、MySQL默认安装路径
  6. VC 实现程序只运行一个实例,并激活已运行的程序
  7. [C#][共享网络] Netsh命令实现共享,并查询连接用户
  8. 【android自定义控件】TextView详解及自定义一
  9. Luogu3825[NOI2017] 游戏
  10. vue3中获取dom元素和操作