随着Javascript的使用变得越来越复杂,以及新标准和技术的产生,Web应用程序每天都在发生着令人惊喜的进步。同时我们也增加了对这些Web应用的依赖性,它们中有很多已经变成我们日常生活中的一部分。我们也知道Web应用开发的不足之一就是在客户端存储数据的能力,直到现在为止,随着HTML5标准和相关技术的成熟,才发生了本质的改变。

Web Storage 是W3C规范,提供了在客户端存储数据的功能,它可以维持数据直到会话结束(Session Storage),或者更久(Local Storage)。Web Storage相比传统的cookies要更加强大,并且易于使用,本文我们将据此展开,同时学习如何使用它。

客户端存储现状

在深入Web Storage之前,我们先简单地回顾一下当前客户端数据存储的技术-cookies-存在哪些问题:

  • 容量小:Cookies可以允许的最大存储为4KB,不适合存储任何复杂数据。
  • 对cookies来说,在相同的站点与多事务处理保持联系不是很容易,比如发生在多个不同窗口或标签(tabs)之间的事务。
  • Cookies可以被跨站脚本等技术所利用,结果可能破坏安全性。

也有一些cookies的替代方案,如将数据存储在查询字符串中、隐藏表单域和基于Flash的本地存储等等技术,这些技术在安全性、使用的方便性以及容量约束方面都或多或少的存在着问题。因此一直以来我们都在使用很差的方式在客户端存储数据,我们需要一种更好的方式,于是Web Storage诞生了。

Web Storage

W3C Web Storage规范 定义了一种在客户端存储数据的更好的方式,它包含两种不同的存储类型:Session Storage和Local Storage。

不管是Session Storage还是Local Storage,它们都能支持在同域下存储5MB数据,这相比cookies有着明显的优势,接下来我们将会详细介绍,并了解其存储机制。

Session Storage

Session Storage的目的只有一个:存储当前会话的所有数据,当你关掉窗口或者标签时立刻丢掉这些数据。

数据的保存和获取

你可以在Session Storage中存储键值对(key value pair)数据,只需要书写一行代码:

sessionStorage.setItem(yourkey, yourvalue);

获取数据可以这样写:

var item = sessionStorage.getItem(yourkey);

通过一行简单的语句向Session Storage存储数据:

sessionStorage.setItem(1, 'The data is stored from csser.com');

这里键为1,但这并不是说这是Session Storage的第一个值,它会转换数值1到字符串“1”来使用,并不会将其对应的值存储在第一个位置。

获取并弹出刚才存储的数据:

var csser = sessionStorage.getItem(1);alert(csser);

另一个setItem()的例子:

sessionStorage.setItem('name', 'CSSer');

然后可以这样获取它:

var name = sessionStorage.getItem('name'); // CSSer

数据的删除和清空

Session Storage也有删除和清空数据的方法,removeItem()用于从Storage列表删除数据:

var item = sessionStorage.removeItem(yourkey);

你也能传入数据项的key从而删除对应的存储数据:

var items = sessionStorage.removeItem(1);

clear()方法用于清空整个列表的所有数据,可以这样使用:

sessionStorage.clear();

同时可以通过使用length属性获取Storage中存储的键值对的个数:

var no_of_items = sessionStorage.length;

Local Storage

Local Storage用于在客户端存储较长时间的数据,一个简单的例子就是用于记录某用户访问该页面的次数。当页面采用Local Storage存储,其被关闭并再次打开后,先前存储的数据仍然存在。

保存和获取Local Storage保存的数据,其工作方式与Session Storage非常相似,它也使用同名方法setItem()和getItem(),要保存数据到Local Storage可以这样写:

localStorage.setItem(1, 'The data is stored local from csser.com');

然后可以这样获取:

var data = localStorage.getItem(1);

同样,Local Storage支持length属性、removeItem()和clear()。

对于Session Storage和Local Storage,clear()函数的目的是相同的—都用于清空列表中的数据,这意味着一旦调用了它,比如localStorage.clear(),它将删除所有同源的本地存储数据,因此所有Local Storage数据都会被清空,像www.csser.com、www.csser.com:80、www.csser.com/category/share/、www.csser.com/category/dev/等,但是,像static.csser.com存储的数据不会受影响。对于Session Storage,它只清空当前会话存储的数据。

使用storage事件

规范同时提供了storage事件( storage event ),当存储区域发生改变时就会被触发,这其中包含许多有用的属性:

  • storageArea : 表示存储类型(Session或Local)
  • key :发生改变项的key
  • oldValue : key的原值
  • newValue : key的新值
  • url : key改变发生的URL

如果调用clear()方法,那么key、oldValue和newValue都会被设置为null。

注意事项

同源存储 :同源存储共享存储空间,同源指一组协议/主机名/端口(或者全局唯一标志符)完全相同。例如:http://www.csser.com和http://static.csser.com就是两个不同的源。

存储限制 :目前为止,大部分浏览器已经实现了Web Storage,并限制每域存储5MB数据。

安全问题 :Storage是以每一个源为基础进行分配,不速之客可能会利用DNS伪装来获取对存储在用户机器的storage区域数据的访问权限,为避免此类事情发生,可以考虑使用SSL技术,因此用户能绝对确信他们访问的是来自相同的域名。

何时不适用 :如果不同的用户使用同一域名的不同路径,他们可以访问整个源的存储区域以及彼此存储的数据。对于使用免费主机的用户,并且站点以相同域名不同目录的形式,不要使用Storage。

最后需要指明的是Web Storage不是HTML5规范的一部分,它是一个独立的规范。