【译】Dive Into HTML5 - Storage(未完结)

原文:THE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS
说明:因个人水平有限,如有误译,欢迎指正。

原生的本地应用相比于 Web 应用在持久化本地存储上具有一定的优势。对于本地应用,操作系统通常会为存储提供一个抽象层并用于获取与应用相关的数据,比如,用户偏好或者运行时状态。这些值可能存储在注册表,INI 文件,XML 文件,或其他取决于平台约定的地方。如果您的原生客户端应用需要除键值对外的本地存储,那么您可以嵌入一个自己的数据库,设计自己的文件格式,等多种解决方案。

因为历史原因,Web 应用没有这些看起来奢侈的功能。早期发明了 Cookie,而且它们确实被用于少量数据的持久化存储。但是它们存在以下三种潜在的缺陷:

  • Cookie 会包含在所有的 HTTP 请求中,因此在不停传输这些数据的情况下降低了 Web 应用的响应速度。
  • 因为 Cookie 包含在了每一个 HTTP 请求中,因此在因特网上传输的数据都是未加密的(除非您的整个应用使用了 SSL)。
  • Cookie 中存储的数据量不得超过 4 KB——这已经足够降低您的应用速度了(参见上面),但是离好用还有很多差距。

我们真正想要的却是:

  • 更大的存储空间
  • 存在于客户端
  • 持久化与页面刷新无关
  • 不会向服务器端传输

在 HTML5 之前,想要实现此目的的所有尝试都不尽如人意。

HTML5 前 hack 本地存储的简短历史

在一开始,我们只能够使用 Internet Explorer 浏览器。或者说,这就是微软所想的。后来,在 第一次浏览器大战 中,Microsoft 发明了很多东西并将它们装进了他们的浏览器,因此,Internet Explorer 赢得了这次战争。这当中,有一个东西叫做 DHTML 行为,其中有一个行为就是 userData。

userData 允许每个域名下面的页面可以存储 64 KB 的数据,使用的是基于 XML 具有层级的结构。(信任的域名,比如 intrant 站点,更能存储 10 倍这样的数据。640 KB 对于任何人来说可以说是足够了。)IE 没有展示任何权限对话框,也不能增加额外的存储空间。

2002 年,Adobe 在 Flash 6 中引入了一个特性,但不幸的是,取了一个具有误导性的名称“Flash cookies”。在 Flash 的环境中,这个特性被称为本地共享对象。简言之,它允许 Flash 对象在每个域名下可以存储 100 KB 的数据。Brad Neuberg 开发了一个名为 AMSSS (AJAX Massive Storage System) 的 Flash-JavaScript 早期原型,但是它却受限于 Flash 的某些设计怪异行为。到 2006 年,随着 Flash 8 ExternalInterface 的发明,可以使用 JavaScript 访问 LSO(本地共享对象)了,不仅更加容易,而且数度也提升了一个量级。Brad 重写了 AMASS 并将其集成进了流行的 Dojo Toolkit 的 moiker dojox.storage 中。Flash 为每个域名提供了“免费的” 100 KB 存储空间,如果超出,则允许按数量级增加(1 MB,10 MB,等等)。

2007 年,Google 正式推出 Gears,一个开源的浏览器插件,致力于在浏览器中提供额外的兼容性。Gears 提供了一个基于 SQLite 的嵌入式 SQL 数据库接口。到 2010 年时,Google 将其重心转移到将所有 Gears 的兼容性带入到类似 HTML5 的 Web 标准中,也正因此,Google Gears 最终终止开发。

与此同时,Brad Neuberg 和其他人持续 hack dojox.storage,以对所有这些不同的插件和 API 提供一个统一的接口。到 2009 年时,dojox.storage 能够自动检测(并在此之上提供一个统一的接口)Adobe Flash,Gears,Adobe AIR,以及一个早期的 HTML5 存储原型,它只在老的 Firefox 中实现。

当您纵览这些解决方案的时候,就会发现一种模式:它们不是特定于某个浏览器,就是依赖于一个第三方插件。尽管也有史诗级的努力来掩盖这些不同(dojox.storage),但是它们暴露了相当不同的接口,拥有不一样的存储限制以及展示了不同的用户体验。所以,这就是 HTML5 着手要去解决的问题:提供一个标准化的 API,原生实现并在多种浏览器上表现一致,且不依赖于第三方插件。

HTML5 存储介绍

我所指的“HTML5 存储(HTML5 Storage)”就是名为 Web Storage 的规范,它曾是 HTML5 规范的一部分,但是因为某些无聊的政治因素而被独立了出去。某些浏览器提供商也将其称之为“Local Storage”或“DOM Storage”。由于某些相关的,相似的命名,新兴的标准,命名的情况变得更加复杂,我在后面将会对其讨论。

那么,什么是 HTML5 存储?简单来说,它是一种 Web 页面在本地存储命名的键值对方式,并存在于客户端 Web 浏览器中。和 Cookie 一样,这个数据在您导航到其它 Web 站点,关闭浏览器选项卡,退出浏览器等情况下依旧被持久化。不同于 Cookie 的是,这个数据从不会发送到远程 Web 服务器(除非您手动发送它)。不像之前所有的提供持久化本地存储的尝试,它是在 Web 浏览器中原生实现的,所以即使在没有第三方插件的情况下,它依旧可用。

哪些浏览器支持?每个浏览器的最新版本都支持 HTML5 存储...即使是 Internet Explorer!Can I use。

在您的 JavaScript 代码中,您可以通过 window 全局对象上的 localStorage 对象访问 HTML5 存储,在使用前应该先 侦测浏览器是否支持它。

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 {
  // no native support for HTML5 storage :(
  // maybe try dojox.storage or a third-party solution
}

使用 HTML5 存储

HTML5 存储是基于命名的键值对。您存储的数据是要有一个命名的键,然后您就可以使用这个键来获取数据。这个命名的键是一个字符串。而数据可以是任何 JavaScript 支持的数据类型,包括字符串,布尔,整型,或浮点型数据。然而,这个数据却是以字符串的形式存储的。如果您想要存储和获取除字符串外的其它数据类型,您将要使用类似 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 对象看作为一个关联型数据,除了使用 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() 时如果使用的是一个不存在的键将不会做任何事。

最后,有一个用于获取整个存储区域值数量的属性,可以通过索引迭代整个键(获取每一个键的名称)。

interface Storage {
  readonly attribute unsigned long length;
  getter DOMString key(in unsigned long index);
};

如果在访问 key() 的时候使用了不在 0 - (length-1) 之间的索引号,那么这个函数将返回 null

你可能感兴趣的:(【译】Dive Into HTML5 - Storage(未完结))