HTML5 Local Storage( 本地存储) 的前世今生
原文连接:http://diveintohtml5.org/storage.html (深入HTML5)
作者:Mark Pilgrim
长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据
例如(用户配置信息或者运行时状态等). 常见的存放这些数据的方式有许多: 注册表,INI文件,XML文件等等。 除了上面这些比较简单的用来存放 键值对的存储形式,如
果你需要使用更加复杂强大的存储,那么你还可以进一步在应用程序中嵌入小型数据库,或者开发出特定的数据文件格式。
3. Cookie的大小限制在4 KB左右。 对于复杂的存储需求来说是不够用的。
对于开发者来说,他们真正需要的是
1. 不受限的存储空间
2. 数据保存在客户端
3. 数据的生命周期可以跨越页面的刷新(甚至浏览器关闭重新打开)
4. 本地数据不必每次都被重复的传回服务器而导致流量增加
在HTML5之前,为了达成上述目标,人们开发出了许多方法,但是总是有一些不尽人意之处。
在互联网发展早期,浏览器市场还很单一(处在领先地位的只有Netscape浏览器和IE)。在 第一次浏览器大战 中,微软的IE为了争取更大的份额,它自己发明了许多额外附加的功能。 这些功能就包括 动态HTML (DHTML) , 而动态HTML中就包含了一种称为 userData 的技术。
userData 允许网页存储最大64KB的基于XML的结构化数据(每个站点) 。获信的站点,例如内网站点,可使用的存储量可以增大到10倍,也即640K。 在使用userData时,IE不会弹出任何形式的对话框来要求用户授权,也不允许程序增加本地存储的容量。
在2002年,Adobe(译者:那个时候其实应该是 Macromedia ) 在Flash6中引入了一个新的本地存储功能,并命名为“Flash Cookies"。 这个名称十分具有迷惑性,其实跟cookie没什么关系。 在Flash中,这个功能被称作 Local Shared Objects 。 简单来说,这个技术允许Flash 对象存储100KB的数据(每个站点 )。 基于此, Brad Neuberg 开发了一个称为 AMASS (AJAX Massive Storage System) Ajax大容量存储系统)的 Flash到JavaScript的桥接原型接口,允许开发者在JavaScript中调用LSO,但是由于Flash的种种技术局限,这个原型并不大好用。 到2006年,随着Flash 8 引入了 ExternalInterface 技术,在JavaScript中访问LSO对象变得简化了许多。这时Brad重写了AMASS并把它整合到了流行的 Dojo Toolkit 框架中, 并正式命名为dojox.storage。 Flash的这种技术允许每个站点存储100KB的数据,超过100KB,则每增加超过一个数量级(如1MB, 10MB 等),它就会弹出对话框来要用户确认并授权。
在2007年,Google启动了著名的 Gears 项目, Gears是一个通过插件技术来增强浏览器功能的开源项目。 Gears提供了一套 API 来访问一个基于 SQLite 的嵌入式SQL数据库, 在获得用户的一次性授权后,应用程序可以通过Gears存储不限数量的本地数据。
与此同时, Brad Neuberg 和其他人继续开发dojox.storage , 希望能够提供一套统一的JavaScript接口来封装上面各种插件和接口。 到2009年时, dojox.storage 已经可以做到自动的侦测用户浏览器所支持的本地存储技术,并提供统一的访问接口,包括Adobe Flash, Adobe AIR, Gears 以及早期 Firefox浏览器所提供的HTML5 存储功能。
从我们前面的介绍可以看到这些五花八门的技术都有一个问题,他们要么是某个浏览器所特有的技术,要么依赖于某个第三方插件(flash或Gears). 虽然Dojox.storage非常有远见的试图去封装这些区别,但是用户仍然会因为底层技术的限制而在用户体验,允许存储的数据量等方面无法统一。 这时,只有HTML5标准的出现才能彻底解决这些问题: 提供一套标准化的API, 被绝大多数浏览器支持,不用依赖任何第三方插件。
这里我们称为HTML Storage的实际上是一个称为 Web Storage 的标准, 它原来曾是HTML5标准的一部分,但由于某些政治因素,现在它被独立出来。 某些浏览器厂商也称它为 本地存储(local storage),或者DOM存储 (DOM Storage)
那么究竟什么是HTML5本地存储 ? 简单来说,它就是一种让网页可以把键值对存储在用户浏览器客户端的方法。像Cookie一样,这些数据不会因为你打开新网站,刷新页面,乃至关闭你的浏览器而消失。 而与Cookie不同的时,这些数据不会每次随着HTTP请求被发送到服务器端(当然如果你需要这么做,你可以自己编程实现 ). 因为这是HTML5规范的一部分,这一接口会被浏览器原生支持,不用依赖任何第三方插件。
那么,现在有哪些浏览器支持这一接口呢? 在这篇文章写作时(译者:2011年2月) 差不多所有主流浏览器的最新版都支持了,连IE8都支持了。
另一种方式是使用 Modernizr (译者:一个开源的用来侦测用户浏览器对HTML5支持度的工具) 来侦测
HTML5 存储是基于键值对的。数据存储在一个键里,访问数据时可以根据同样的键获得上次存储的数据. 键是一个字符串. 而数据则可以是任何类型的JavaScript基本数据类型,包括 字符串,Boolean,整数,和浮点数. 不过需要注意的是,这些数据在存储时实际上是以字符串保存的。 因此在访问数据时你需要利用parseInt() 或 parseFloat()方法来做数据类型的转换。
如果在调用setItem 时使用一个已经存在的键,将会直接覆盖掉该键上保存的值。而调用getItem时传入一个不存在的键,则会返回一个null ,不会抛出异常。
该接口还提供了方法来删除某个键和清空整个存储区域(删除所有的键和值)
如果removeItem传入一个不存在的key则无操作,也不会有异常。
最后,还提供了一个length属性来指示存储区域中所包含的所有键值对的数量 以及遍历所有键的key方法
原文连接:http://diveintohtml5.org/storage.html (深入HTML5)
作者:Mark Pilgrim
译者 : feijia (tiimfei@gmail.com)
译者的话:上周读到这篇关于html5 local storage 的综述性文章觉得十分受益。这篇文章是作者的书HTML5 up & Running的的一个章节,并在线以 CC-BY-3.0 License授权。 可以看到dojox.storage 是在HTML5标准成型前整个业界唯一提供统一的本地存储接口的框架。 即使是在今天,为了兼顾用户较早版本浏览器的兼容性,dojox.storage 仍然有很大的作用. 文章较长,分两部分翻译。 今天是第一部分。
长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据
例如(用户配置信息或者运行时状态等). 常见的存放这些数据的方式有许多: 注册表,INI文件,XML文件等等。 除了上面这些比较简单的用来存放 键值对的存储形式,如
果你需要使用更加复杂强大的存储,那么你还可以进一步在应用程序中嵌入小型数据库,或者开发出特定的数据文件格式。
遗憾的是,上面这些本地存储方法对Web应用来说都是不适用的。在Web的发展史上,在很长时间里 Cookies是唯一可以使用的在用户本地存储少量数据的方法。 但Cookies有一些非常明显的缺陷,限制了它的应用:
1. cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
3. Cookie的大小限制在4 KB左右。 对于复杂的存储需求来说是不够用的。
对于开发者来说,他们真正需要的是
1. 不受限的存储空间
2. 数据保存在客户端
3. 数据的生命周期可以跨越页面的刷新(甚至浏览器关闭重新打开)
4. 本地数据不必每次都被重复的传回服务器而导致流量增加
在HTML5之前,为了达成上述目标,人们开发出了许多方法,但是总是有一些不尽人意之处。
在HTML5之前的本地存储的简史
在互联网发展早期,浏览器市场还很单一(处在领先地位的只有Netscape浏览器和IE)。在 第一次浏览器大战 中,微软的IE为了争取更大的份额,它自己发明了许多额外附加的功能。 这些功能就包括 动态HTML (DHTML) , 而动态HTML中就包含了一种称为 userData 的技术。
userData 允许网页存储最大64KB的基于XML的结构化数据(每个站点) 。获信的站点,例如内网站点,可使用的存储量可以增大到10倍,也即640K。 在使用userData时,IE不会弹出任何形式的对话框来要求用户授权,也不允许程序增加本地存储的容量。
在2002年,Adobe(译者:那个时候其实应该是 Macromedia ) 在Flash6中引入了一个新的本地存储功能,并命名为“Flash Cookies"。 这个名称十分具有迷惑性,其实跟cookie没什么关系。 在Flash中,这个功能被称作 Local Shared Objects 。 简单来说,这个技术允许Flash 对象存储100KB的数据(每个站点 )。 基于此, Brad Neuberg 开发了一个称为 AMASS (AJAX Massive Storage System) Ajax大容量存储系统)的 Flash到JavaScript的桥接原型接口,允许开发者在JavaScript中调用LSO,但是由于Flash的种种技术局限,这个原型并不大好用。 到2006年,随着Flash 8 引入了 ExternalInterface 技术,在JavaScript中访问LSO对象变得简化了许多。这时Brad重写了AMASS并把它整合到了流行的 Dojo Toolkit 框架中, 并正式命名为dojox.storage。 Flash的这种技术允许每个站点存储100KB的数据,超过100KB,则每增加超过一个数量级(如1MB, 10MB 等),它就会弹出对话框来要用户确认并授权。
在2007年,Google启动了著名的 Gears 项目, Gears是一个通过插件技术来增强浏览器功能的开源项目。 Gears提供了一套 API 来访问一个基于 SQLite 的嵌入式SQL数据库, 在获得用户的一次性授权后,应用程序可以通过Gears存储不限数量的本地数据。
与此同时, Brad Neuberg 和其他人继续开发dojox.storage , 希望能够提供一套统一的JavaScript接口来封装上面各种插件和接口。 到2009年时, dojox.storage 已经可以做到自动的侦测用户浏览器所支持的本地存储技术,并提供统一的访问接口,包括Adobe Flash, Adobe AIR, Gears 以及早期 Firefox浏览器所提供的HTML5 存储功能。
从我们前面的介绍可以看到这些五花八门的技术都有一个问题,他们要么是某个浏览器所特有的技术,要么依赖于某个第三方插件(flash或Gears). 虽然Dojox.storage非常有远见的试图去封装这些区别,但是用户仍然会因为底层技术的限制而在用户体验,允许存储的数据量等方面无法统一。 这时,只有HTML5标准的出现才能彻底解决这些问题: 提供一套标准化的API, 被绝大多数浏览器支持,不用依赖任何第三方插件。
HTML5 本地存储简介
这里我们称为HTML Storage的实际上是一个称为 Web Storage 的标准, 它原来曾是HTML5标准的一部分,但由于某些政治因素,现在它被独立出来。 某些浏览器厂商也称它为 本地存储(local storage),或者DOM存储 (DOM Storage)
那么究竟什么是HTML5本地存储 ? 简单来说,它就是一种让网页可以把键值对存储在用户浏览器客户端的方法。像Cookie一样,这些数据不会因为你打开新网站,刷新页面,乃至关闭你的浏览器而消失。 而与Cookie不同的时,这些数据不会每次随着HTTP请求被发送到服务器端(当然如果你需要这么做,你可以自己编程实现 ). 因为这是HTML5规范的一部分,这一接口会被浏览器原生支持,不用依赖任何第三方插件。
那么,现在有哪些浏览器支持这一接口呢? 在这篇文章写作时(译者:2011年2月) 差不多所有主流浏览器的最新版都支持了,连IE8都支持了。
IE | Firefox | Safari | Chrome | Opera | iPhone | Android |
---|---|---|---|---|---|---|
8.0+ | 3.5+ | 4.0+ | 4.0+ | 10.5+ | 2.0+ | 2.0+ |
- function supports_html5_storage() {
- try {
- return 'localStorage' in window && window['localStorage'] !== null;
- } catch (e) {
- return false;
- }
- }
另一种方式是使用 Modernizr (译者:一个开源的用来侦测用户浏览器对HTML5支持度的工具) 来侦测
- if (Modernizr.localstorage) {
- // window.localStorage is available!
- } else {
- // 浏览器不支持HTML5 storage :(
- // 可以考虑使用dojox.storage 或其他方法
- }
如何使用HTML5 存储
HTML5 存储是基于键值对的。数据存储在一个键里,访问数据时可以根据同样的键获得上次存储的数据. 键是一个字符串. 而数据则可以是任何类型的JavaScript基本数据类型,包括 字符串,Boolean,整数,和浮点数. 不过需要注意的是,这些数据在存储时实际上是以字符串保存的。 因此在访问数据时你需要利用parseInt() 或 parseFloat()方法来做数据类型的转换。
- interface Storage {
- getter any getItem(in DOMString key);
- setter creator void setItem(in DOMString key, in any data);
- };
如果在调用setItem 时使用一个已经存在的键,将会直接覆盖掉该键上保存的值。而调用getItem时传入一个不存在的键,则会返回一个null ,不会抛出异常。
就像其他JavaScript对象一样,你也可以将localStorage对象当成是关联数组使用(associative map)
除了使用getItem和setItem之外,你可以使用中括号的方式来引用数据. 例如
- var foo = localStorage.getItem("bar");
- // ...
- localStorage.setItem("bar", foo);
- //和下面代码是等价的:
- var foo = localStorage["bar"];
- // ...
- localStorage["bar"] = foo;
该接口还提供了方法来删除某个键和清空整个存储区域(删除所有的键和值)
- interface Storage {
- deleter void removeItem(in DOMString key);
- void clear();
- };
如果removeItem传入一个不存在的key则无操作,也不会有异常。
最后,还提供了一个length属性来指示存储区域中所包含的所有键值对的数量 以及遍历所有键的key方法
- interface Storage {
- readonly attribute unsigned long length;
- getter DOMString key(in unsigned long index);
- };
如果你向key方法传入了一个越界的值(不在0到length-1 之间),则该方法返回null。