[原文地址]: DOM Storage guide
概述
DOM存储是一套在 Web Applications 1.0 规范中首次引入的与 存储相关的特性 的总称, 现在已经分离出来,单独发展成为独立的 W3C Web存储 规范. DOM存储被设计为用来提供一个更大存储量,更安全,更便捷的存储方法,从而可以代替掉将一些不需要让服务器知道的信息存储到cookies里的这种传统方法.该特性在 Firefox 2 和 Safari 4 中首次引入.
描述
DOM存储的机制是通过存储字符串类型的键/值对,来提供一种安全的存取方式.这个附加功能的目标是提供一个全面的,可以用来创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间).
基于Mozilla的浏览器, Internet Explorer 8+, Safari 4+ 以及 Chrome 都提供了自己的DOM存储规范的实现. (如果你想让自己的代码兼容多个浏览器,则你需要照顾一下老版本的IE浏览器,IE下有一个类似的特性,在IE8之前版本也可以使用,叫做" userData behavior ",它允许你在多重浏览器会话中永久地保存数据.)
DOM存储是非常有用的,因为浏览器没有好的方法在任何一段时间存储大量的数据。浏览器的cookie容量有限,而且也不支持组织处理已存在的数据,其它的一些方法(比如Flash的本地存储)需要外部的插件。
Halfnote是由Aaron Boodman所编写的首次使用DOM Storage功能的公共程序之一(除了ie浏览器的userData行为)。在Aaron Boodman的程序中,Aaron将记录同时保存到服务器(当网络连接可用的时候)和本地数据库中。这样,便可以使得用户安全的写备份记录,即使只能偶尔连接上网络。
尽管这个概念和实施在Halfnote看来是非常简单的,但是它却创造性的展示了一种在线和离线时都可用的新型web应用程序的可能性。
参考
以下所提到的对象都是全局对象,作为
window 对象
的属性存在。这意味着可以以
sessionStorage
或者
window.sessionStorage 的形式访问这些对象。
(这是很重要的,因为可以使用IFrames来存储、访问附加数据,而不是将这些数据立即包含在当前页面中)
Storage
对于所有的Storage实体都存在一个构造方法(sessionStorage和globalStorage)。设置Storage.prototype.removeKey=function(key) { this.removeItem(this.key(key);} 将会在使用localStorage.removeKey和sessionStorage.removeKey时被访问。 globalStorage中的项不是Storage的实例,但却是StorageObsolete的实例。 Storage通过Storage Interface进行如下定义
interface Storage { readonly attribute unsigned long length; [IndexGetter] DOMString key(in unsigned long index); [NameGetter] DOMString getItem(in DOMString key); [NameSetter] void setItem(in DOMString key, in DOMString data); [NameDeleter] void removeItem(in DOMString key); void clear(); };
.toString
方法被转换成字符串。所以一个普通对象将会被存储为
"[object Object]"
,而不是对象本身或者它的 JSON 形式。使用浏览器自身提供的 JSON 解析和序列化方法来存取对象是比较好的,也是比较常见的方法。
sessionStorage
sessionStorage
是个全局对象,它维护着
在页面会话(page session)期间有效的
存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。
// 保存数据到当前会话的存储空间 sessionStorage.setItem("username", "John"); // 访问数据 alert( "username = " + sessionStorage.getItem("username"));
当浏览器被意外刷新的时候,一些临时数据应当被保存和恢复。
sessionStorage
对象在处理这种情况的时候是最有用的。
在Firefox 3.5之前的版本中,如果浏览器意外崩溃,则在重启后,sessionStorage中保存的数据不会被恢复.之后的版本中,会恢复上次崩溃前的sessionStorage数据.
例子:
自动保存一个文本域中的内容,如果浏览器被意外刷新,则恢复该文本域中的内容,所以不会丢失任何输入的数据。
// 获取到我们要循环保存的文本域 var field = document.getElementById("field"); // 查看是否有一个自动保存的值 // (只在浏览器被意外刷新时) if ( sessionStorage.getItem("autosave")) { // 恢复文本域中的内容 field.value = sessionStorage.getItem("autosave"); } // 每隔一秒检查文本域中的内容 setInterval(function(){ // 并将文本域的值保存到session storage对象中 sessionStorage.setItem("autosave", field.value); }, 1000);
更多信息:
localStorage
localStorage 在Firefox 3.5中被引进。
兼容性
这些
Storage
对象最近刚被加入标准当中,所以并不是所有的浏览器都支持。如果你想在没有原生支持
localStorage
对象的浏览器中使用它,可以在你编写的 JavaScript 代码的首部插入下面两段代码中的任意一段。
This algorithm is an exact imitation of the
localStorage
object, but making use of cookies.
if (!window.localStorage) { Object.defineProperty(window, "localStorage", new (function () { var aKeys = [], oStorage = {}; Object.defineProperty(oStorage, "getItem", { value: function (sKey) { return sKey ? this[sKey] : null; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "key", { value: function (nKeyId) { return aKeys[nKeyId]; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "setItem", { value: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "length", { get: function () { return aKeys.length; }, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "removeItem", { value: function (sKey) { if(!sKey) { return; } var sExpDate = new Date(); sExpDate.setDate(sExpDate.getDate() - 1); document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/"; }, writable: false, configurable: false, enumerable: false }); this.get = function () { var iThisIndx; for (var sKey in oStorage) { iThisIndx = aKeys.indexOf(sKey); if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } else { aKeys.splice(iThisIndx, 1); } delete oStorage[sKey]; } for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) { iCouple = aCouples[iCouplId].split(/\s*=\s*/); if (iCouple.length > 1) { oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]); aKeys.push(iKey); } } return oStorage; }; this.configurable = false; this.enumerable = true; })()); }
localStorage.setItem()
和
localStorage.removeItem()方法来增加,更改或删除一个键值。使用
localStorage.yourKey = yourValue;和
delete localStorage.yourKey;的方法来设置或删除一个键值,这些代码都不是一种安全的方式。你也可以改变它的名字和仅仅使用它来管理文档的cookies而不必理睬
localStorage对象。 localStorage的对象。它比之前的更简单,但却兼容老版本的浏览器,
如Internet Explorer <8。这也得使用cookies.
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } var sExpDate = new Date(); sExpDate.setDate(sExpDate.getDate() - 1); document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }
与 globalStorage 的关系的兼容性
localStorage与globalStorage类似,区别在于所属HTML5的域,并且localStorage是Storage的一个实例,而globalStorage是StorageObsolete的一个实例。
例如,在
http://example.com
中不能访问
https://example.com
中的
localStorage
对象,但是它们都可以访问同一个
globalStorage。
localStorage
是个标准接口,但
globalStorage
是非标准的。所以你的代码最好不要依赖这些关系。
注意:设置globalStorage的属性不会对localStorage属性的设置产生影响,并且通过扩展Storage.prototype也不会影响globalStorage中的项。然而,使用StorageObsolete.prototype扩展会对globalStorage中的项产生影响。当浏览器进入到私有浏览模式时,会建立一个新的临时数据库来存储storage数据。当私有浏览模式关闭时,便会将这个数据库删除。
globalStorage
非标准
已废弃 Gecko 13.0 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10)
globalStorage
在
Gecko 1.9.1 (Firefox 3.5) 时就被废弃,从Gecko
13 (Firefox 13)起就不在被支持. 而是使用localStorage
. This proposed addition to HTML 5 has been removed from the HTML
5 specification in favor of <code>localStorage</code>, which
is implemented in Firefox 3.5. This is a global object (
globalStorage
) that maintains multiple private storage areas that can be used to hold
data over a long period of time (e.g. over multiple pages and browser sessions).
globalStorage 不是一个
Storage
实例
,而是一个包含StorageObsolete对象的
StorageList实例
// Save data that only scripts on the mozilla.org domain can access globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");
特别来说,globalStorage对象提供了对一些不同storage对象的访问,这些storage对象存储着相关数据。例如,可以建立一个Web页面,并在当前域(developer.mozilla.org)中使用glogalStorage,可以获得以下有用的storage对象:
-
globalStorage['developer.mozilla.org']
- All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.
例子:
以下示例要求在每一个Web页面中都要存在一个所想展示结果的JavaScript。 保存当前正在访问的特定子域内的用户名称。
保存当前正在访问的特定子域内的用户名称:
globalStorage['developer.mozilla.org'].setItem("username", "John");
保存当前正在访问的特定子域内的用户名称:
// parseInt must be used since all data is stored as a string globalStorage['mozilla.org'].setItem("visits", parseInt(globalStorage['mozilla.org'].getItem("visits") || 0 ) + 1);
存储位置以及清除数据
In Firefox the DOM storage data is stored in the webappsstore.sqlite file in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, notably for the start page - about:home , but potentially for other internal pages with "about:" URLs).
-
DOM Storage can be cleared via "Tools -> Clear Recent History ->
Cookies" when Time range is "Everything" (via nsICookieManager::removeAll)
- But not when another time range is specified: (bug 527667)
- Does not show up in Tools -> Options -> Privacy -> Remove individualcookies (bug 506692)
- DOM Storage is not cleared via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.
- Doesn't show up in the "Tools -> Options -> Advanced -> Network -> Offline data" list, unless the site also uses the offline cache. If the site does appear in that list, its DOM storage data is removed along with the offline cache when clicking the Remove button.
See also clearing offline resources cache .
更多信息
- Web Storage (W3C Web Apps Working Group)
- Enable/Disable DOM Storage in Firefox or SeaMonkey
例子
- JavaScript Web Storage Tutorial: Creating an Address Book Application - hands-on tutorial describing how to use the Web Storage API by creating a simple address book application
- offline web applications at hacks.mozilla.org - showcases an offline app demo and explains how it works.
- Noteboard - Note writing application that stores all data locally.
- jData - A shared localStorage object interface that can be accessed by any website on the internet and works on Firefox 3+, Webkit 3.1.2+ nightlies, and IE8. Think of it as pseudo-globalStorage[""] but write access needs user confirmation.
- HTML 5 localStorage example . Very simple and easy to understand example of localStorage. Saves and retrieves texts and shows a list of saved items. Tested in Firefox 3 or higher.
- HTML5 Session Storage . A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.
-
Basic DOMStorage Examples- Broken in Firefox 3 and up due to use of globalStorage on one domain level up from the current domain which is not allowed in Firefox 3. halfnote- (displaying broken in Firefox 3) Note writing application that uses DOM Storage.
浏览器兼容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
localStorage | 4 | 3.5 | 8 | 10.50 | 4 |
sessionStorage | 5 | 2 | 8 | 10.50 | 4 |
globalStorage | Not supported | 2-13 | Not supported | Not supported | Not supported |
All browsers have varying capacity levels for both local- and sessionStorage. Here is adetailed rundown of all the storage capacities for various browsers .
相关链接
-
HTTP cookies(
document.cookie
) - Flash Local Storage
- Internet Explorer userData behavior
- nsIDOMStorageEventObsolete
- StorageEvent
HTML5 Documentation | |
---|---|
HTML | |
JavaScript | |
CSS |
---------------------------------
摘要
DOM Storage,就是在Web Applications 1.0specification中介绍的那些存储相关特性集合的名称。相比较在cookies中存储信息来说,DOM Stroage更大、更安全、更易于使用的。目前支持的浏览器包括Mozilla Firefox2+, Google Chrome, Apple Safari, Opera和Microsoft IE9+,在移动设备上也包括iPhone &iPad Safari。
描述
DOM Storage机制是一种通过字符串形式的名/值对来安全地存储和使用的方法。这个附加功能的目标是提供一个更全面的、可以创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间)。
目前,只有基于Mozilla的浏览器提供了DOM Storage的实现。不过,Internet Explorer也有一个类似的特性,叫做" userData behavior ",他允许你在多重浏览器会话中永久地保存数据。
DOM Storage 是很有用的,因为在任何一段时期都没有一个很好的、只通过浏览器来永久存储合理大小的数据的方法。 浏览器cookies限制了存储容量,而且并没有为组织永久性的数据提供支持,并且其他的方法还需要外部插件来实现(例如 Flash Local Storage )。
第一个使用了新的DOM Storage功能(除了Internet Explorer 的 userData Behavior之外)的公共应用程序是由 Aaron Boodman 写的 halfnote (一个便签应用程序) 。在他的程序中,Aaron同时把便签内容保存到服务器上(当Internet连接可用时)和一个本地数据存储中。这就允许用户即便是在不定式发生internet连接中断时,也可以安全的写一些有备份的便签。
不过,在halfnote中表现出来的概念和实现,都还是相对简单的。它的诞生揭示了一种新的、可以在线或离线使用的网络应用程序。
参考
下面的内容都是作为每个window
对象的属性存在的全局对象。这也就是说,可以通过sessionStorage
或者window.sessionStorage
来访问它们。(这很重要,因为随后你可以使用iframe来存储、访问、添加那些并不是立刻就包含在你页面中的数据。)
sessionStorage
这是一个全局对象(sessionStorage
),它含有一个在页面会话有效期内可用的存储区域。只要页面没有关闭,一个页面会话就始终保持着,并且当页面被重新载入或恢复时“复活”。打开一个新的标签页或新窗口都会初始化新的会话。
// 保存数据到当前会话的存储空间 sessionStorage.setItem("username", "John"); // 访问数据 alert( "username = " + sessionStorage.getItem("username"));
sessionStorage
对象是最有用的,它持有那些应该保存的临时数据,而且一旦浏览器突然被刷新时,要恢复的那些数据,
sessionStorage
还应该有在浏览器崩溃后存储和恢复数据的功能,不过由于
bug 339445的原因,这个功能到现在还没有在Firefox中实现。这个功能实现之后,sessionStorage
的防御功能就十分有用了。
举例:
自动保存文本字段的内容,如果浏览器突然被刷新,就恢复字段内容,这样就不会丢失任何输入了。
// 获得我们要跟踪的那个文本字段 var field = document.getElementById("field"); // 看看我们是否有一个autosave的值 // (这将只会在页面被突然刷新时发生) if ( sessionStorage.autosave ) { // 恢复文本字段中的内容 field.value = sessionStorage.autosave; } // 每秒钟检查一次文本字段的内容 setInterval(function(){ // 并把结果保存到会话存储对象中 sessionStorage.autosave = field.value; }, 1000);
更多信息:
globalStorage
这是一个全局对象(globalStorage
),它维护着各种公共的或者私有的,可以用来长时期保存数据的存储空间(例如,在多重的页面和浏览器会话之间)。
// 可以这样访问那些仅对mozilla.org域上的脚本保存的数据 globalStorage['mozilla.org'].snippet = "Hello, how are you?"; // 可以这样访问为任何网页任何域存储的数据 globalStorage[''].favBrowser = "Firefox";
特别地,globalStorage
对象,提供了访问一些不同的可以保存数据的存储对象的方法。例如,如果我们要建立一个可以在域(developer.mozilla.org)下面可以使用
globalStorage
的网页,我们有下面这些存储对象可以使用:
-
globalStorage['developer.mozilla.org']
- 在developer.mozilla.org下面所有的子域都可以通过这个存储对象来进行读和写。 -
globalStorage['mozilla.org']
- 在mozilla.org域名下面的所有网页都可以通过这个存储对象来进行读和写。 -
globalStorage['org']
- 在.org域名下面的所有网页都可以通过这个存储对象来进行读和写。 globalStorage[]
- 在任何域名下的任何网页都可以通过这个存储对象来进行读和写。
示例:
下面这些示例,需要你在所有想看到效果的页面中都插入脚本(包括如下所有的代码)。
记录某个指定子域名下面正在访问的用户的username:
globalStorage['developer.mozilla.org'].username = "John";
跟踪一个用户在你的域名下所访问的所有页面的次数:
// 由于所有数据都是被当作一个字符串来保存的,所以这里必须使用parseInt globalStorage['mozilla.org'].visits = parseInt( globalStorage['mozilla.org'].visits || 0 ) + 1;
记录所有你访问的网站:
globalStorage[''].sites += "," + location.hostname;
更多信息:
更多信息
- Web Applications 1.0 Specification
- Web Applications 1.0 Storage Specification
- Enable/Disable DOM Storage in Firefox or SeaMonkey
例子
- Basic DOMStorage Examples
- halfnote- Note writing application that uses DOM Storage.