12.27 HTML 本地存储(Local Storage)

HTML本地存储允许在本地浏览器中存储数据

如课程引言中所述,本地应用程序(如移动APP)能够利用本地操作系统的文件系统来存储和读取数据,这使得其可以在离线环境下工作,由于节省了大量网络数据传输,从而可以获得更高的性能。 HTML5里面引入的本地存储(Local Storage)接口就是为了达到相同的目的,把部分客户端数据保存在本地浏览器中,从而提高Web应用的性能。 和Cookie类似,本地存储也是和源(origin,也就是域名、协议和端口的组合)相关的,现代浏览器给本地存储提供了5到10M大小的空间(每个域)。

在HTML5之前,我们是通过Cookie来存储数据在浏览器中,Local Storage比Cookie强大的地方在于:1.容量更大 2.不需要传输给服务器。

浏览器支持

API
Web Storage 4.0 8.0 3.5 4.0 11.5

Local Storage对象

HTML5 提供了两种在客户端存储数据的新方法:

  • window.localStorage - 没有时间限制的数据存储
  • window.sessionStorage - 对于一个会话(session)的数据存储,当浏览器标签被关闭时丢失

window.localStorage和localStorage在代码中是等同的。

在使用Local Storage之前,先检查一下浏览器是否支持:

if(typeof(Storage) !== "undefined") {
    // Code for localStorage/sessionStorage.
} else {
    // Sorry! No Web Storage support..
}}

localStorage的存取

localStorage对象存储的数据没有到期日期。当浏览器关闭时,数据不会被删除,而会一直存在。

// 保存
localStorage.setItem("nickname", "iefreer");
// 读取
document.getElementById("result").innerHTML = localStorage.getItem("nickname");

代码解释如下:

  • 创建一个localStorage名/值对(name/value),其中name="nickname",value="iefreer"。
  • 读取刚才保存的用户昵称数据,并显示在id为result元素中。

上面的代码还可以简写为下面这样:

// 保存
localStorage.nickname = "iefreer";
// 读取
document.getElementById("result").innerHTML = localStorage.nickname;

如果要删除该数据,可以使用如下代码:

// 删除
localStorage.removeItem("lastname");

如果要清空本地存储,可以使用如下代码:

// 删除
localStorage.clear();

名/值对只能保存字符串,当需要保存数字时,记得要转换格式。

下面的例子对用户访问页面的次数进行计数,在该例中value字符串被转换成数字来增加计数:

if (localStorage.pagecount){
localStorage.pagecount=Number(localStorage.pagecount) +1;
}else{
localStorage.pagecount=1;
}
document.write("Visits "+ localStorage.pagecount + " time(s).");

数组

除了使用setItem和getItem,我们还可以在Local Storage中保存数组数据:

localStorage["key1"]="value1";
 var value=localStorage["key1"];

Local Storage还提供了一个length属性和一个key方法来操作数组:

for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
var value = localStorage[key];
alert(value);
}

我们也可以使用如下简化循环语法(for in的方式称之为foreach语法):

for (var key in localStorage) {
var value = localStorage[key];alert(value); }

如果要删除某个数据,我们可以使用localStorage.removeItem(key);

会话存储(sessionStorage)语法

sessionStorage对象和localStorage对象用法一样,上面关于localStorage的代码,替换成sessionStorage一样工作。 唯一的差别在于sessionStorage存储的数据只在一个会话期间有效。也就是当用户关闭浏览器窗口时,该数据被删除。

查看本地存储数据

现代浏览器如Chrome都提供了开发工具可以用来查看本地存储数据,如下图所示:

在浏览器中查看本地存储数据

本地存储限制

如果本地存储的数据超过了浏览器能提供的空间的上限时,浏览器会抛出一个异常:QUOTA_EXCEEDED_ERR,所以应用程序应该把数据存储的代码放在try catch对中,以免导致浏览器崩溃。 你可以使用如下的代码来测试这种情况:

localStorage.setItem("blow", "-");
while (true) {
    var blow = localStorage.getItem("blow");
    try {
        localStorage.setItem("blow", blow + blow);
    } catch (e) {
        alert("Your browser blew up at <" + blow.length + ">bytes with exception: " + e);
        break;
    }
}
localStorage.removeItem("blow");

本地存储的编程规范

  • 没有HTML5官方的本地存储命名规范,但是由于当同一域名下的不同应用产生名称冲突时会出现数据覆盖,我们需要建立起良好的编码习惯。
  • 如果你想要保存较多的数组或对象列表数据到本地存储中时,建议使用JSON.stringify来保存并使用JSON.parse来读取该数据。这样序列化后占用的空间更小。

关于命名,我们建议的方式是为变量加上应用ID的前缀,如下图所示:

本地存储命名规范

实现一个在线待办事项应用

除了记住用户偏好外,一个典型的本地存储应用是日程安排,我们把这个作为一个课程练习。要实现如下功能:

  • 一个简单的列表页面和一排操作按钮用来添加或清除某个事项
  • 可以实时保存待办事项,并可以从本地存储中加载以前的数据

你可以先自己尝试实现下,然后可以参考在线实例(该实例甚至实现了一个3D的界面效果):http://wow.techbrood.com/fiddle/15268

到目前为止,我们学习到的内容都比较有趣,但是接下来,我们要讲述的HTML5多线程双工通信方面的技术, 对于前端工程师而言可能就偏晦涩,需要对计算机操作系统和网络通信协议有更为深入的了解。不过如果你不需要实现高性能计算或即时通讯方面的网页应用,可以暂时忽略这些章节。