凌动小生的Blog

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 localStorage 和 sessionStorage

实现了”Web存储“草案标准的浏览器在window对象上定义了两个属性:localStorage和sessionStorage。这两个属性都代表同一个Storage对象——一个持久化关联数组,数组使用字符串来索引,存储的值也都是字符串形式的。Storage对象在使用上和一般的JavaScript对象没什么区别:设置对象的属性为字符串值,随后浏览器会将该值存储起来。localStorage和sessionStorage两者的区别在于存储的有效期和作用域的不同:数据可以存储多长时间以及谁拥有数据的访问权。

下面,我们会对存储的有效期和作用域作详细的解释。不过,在此之前,让我们先来看些例子。下面的代码使用的是localStorage,但是它对sessionStorage也同样适用:

var name = localStorage.username; // 查询一个存储的值。
name = localStorage["username"]; // 等价于数组表示法
if (!name) {
    name = prompt("What is your name?"); // 询问用户一个问题。
    localStorage.username = name; // 存储用户的答案。
}

// 迭代所有存储的name/value对
for(var name in localStorage) { // 迭代所有存储的名字
    var value = localStorage[name]; // 查询每个名字对应的值
}

Storage对象还定义了一些诸如存储、获取、遍历和删除的方法。这些方法会在§20.1.2中作介绍。

”Web存储”草案标准指出,我们既可以存储结构化的数据(对象和数组),也可以存储原始类型数据,还可以存储诸如日期、正则表达式甚至文件对象在内的内置类型的数据。但是,截止至本书截稿时,浏览器仅仅支持存储字符串类型数据。如果想要存储和获取其他类型的数据,不得不自己手动进行编码和解码。如下例子所示:

// 当存储一个数字的时候,它会被自动转换成字符串。
// 但是,当获取该值的时候别忘记了手动将其转换成数字类型。
localStorage.x = 10;
var x = parseInt(localStorage.x);

// 同样地,存储一个日期类型数据的时候进行编码,获取的时候进行解码
localStorage.lastRead = (new Date()).toUTCString();
var lastRead = new Date(Date.parse(localStorage.lastRead));

// 使用JSON可以使得对基本数据类型编码的工作变得很方便
localStorage.data = JSON.stringify(data); // 编码然后存储。
var data = JSON.parse(localStorage.data); // 获取数值之后再解码。

20.1.1 存储有效期和作用域

localStorage和sessionStorage的区别在于存储的有效期和作用域的不同。通过localStorage存储的数据是永久性的,除非web应用刻意删除存储的数据,或者用户通过设置浏览器配置(浏览器提供的配置界面)来删除,否则数据将一直保留在用户的电脑上,永不过期。

localStorage的作用域是限定在文档源(document origin)级别的。正如§13.6.2所介绍的,文档源是通过协议、主机名以及端口三者来确定的,因此,下面每个URL都拥有不同的文档源:

http://www.example.com              // 协议: http; 主机名: www.example.com
https://www.example.com            // 不同协议
http://static.example.com              // 不同主机名
http://www.example.com:8000      // 不同端口

同源的文档间共享同样的localStorage数据(不论该源的脚本是否真正地操作localStorage)。它们可以互相读取对方的数据,甚至可以覆盖对方的数据。但是,非同源的文档间互相都不能读写对方数据(即使它们运行的脚本是来自同一台第三方服务器也不行)。

需要注意的是localStorage的作用域也受浏览器供应商限制。如果你使用Firefox访问站点,那么下次用另一个浏览器比方说是Chrome再次访问的时候,那么本次是无法获取上次存储的数据的。

通过sessionStorage存储的数据和通过localStorage存储的数据的有效期也是不同的:前者有效期和存储数据的脚本所在的最顶层的窗口或者是浏览器标签页是一样的。一旦窗口或者标签页被永久关闭了,那么所有通过sessionStorage存储的数据也都被删除了。(当时要注意的是,现代浏览器已经具备了重新打开最近关闭的标签页随后恢复上一次浏览的session功能,因此,这些标签页以及与之相关的sessionStorage的有效期可能会更加长些)。

与localStorage一样,sessionStorage的作用域也是限定在文档源中,因此非同源文档间都是无法共享sessionStorage的。不仅如此,sessionStorage 的作用域还被限定在窗口中。如果同源的文档渲染在不同的浏览器标签页中,那么他们互相之间拥有的是各自的sessionStorage数据,无法共享;一个标签页中的脚本是无法读取或者覆盖由另一个标签页脚本写入的数据,哪怕这两个标签页渲染的是同一个页面,运行的是同一个脚本也不行。

要注意的是:这里提到的基于窗口作用域的sessionStorage指的窗口只是顶级窗口。如果一个浏览器标签页包含两个<iframe>元素,他们所包含的文档是同源的,那么这两者之间是可以共享sessionStorage的。

posted on 2012-08-10 10:11  凌动小生  阅读(1000)  评论(0编辑  收藏  举报