DOM Storage guide

  • Revision slug: DOM/Storage
  • Revision title: DOM Storage
  • Revision id: 42689
  • Created:
  • Creator: Jürgen Jeka
  • Is current revision? No
  • Comment "globalStorage" dropped in Gecko 13; 21 words added, 1 words removed

Revision Content

Summary

DOM Storage is the name given to the set of storage-related features first introduced in the Web Applications 1.0 specification, and now split off into its own W3C Web Storage specification. DOM Storage is designed to provide a larger, more secure, and easier-to-use alternative to storing information in cookies. It was first introduced with Firefox 2 and Safari 4.

Note: DOM Storage is not the same as mozStorage (Mozilla's XPCOM interfaces to SQLite) or the Session store API (an XPCOM storage utility for use by extensions).

Description

The DOM Storage mechanism is a means through which string key/value pairs can be securely stored and later retrieved for use. The goal of this addition is to provide a comprehensive means through which interactive applications can be built (including advanced abilities, such as being able to work "offline" for extended periods of time).

Mozilla-based browsers, Internet Explorer 8+, Safari 4+ and Chrome all provide a working implementation of the DOM Storage specification. (In case you need this functionality cross-browser and you need to cater for older versions of IE, it may be useful to note that Internet Explorer also has a similar legacy feature called "userData behavior" that predates the addition of DOM Storage to IE in IE8.)

DOM Storage is useful because no good browser-only methods exist for persisting reasonable amounts of data for any period of time. Browser cookies have limited capacity and provide no support for organizing persisted data, and other methods (such as Flash Local Storage) require an external plugin.

One of the first public applications to make use of the new DOM Storage functionality (in addition to Internet Explorer's userData Behavior) was halfnote (a note-taking application) written by Aaron Boodman. In his application, Aaron simultaneously saved notes back to a server (when Internet connectivity was available) and a local data store. This allowed the user to safely write backed-up notes even with sporadic Internet connectivity.

While the concept, and implementation, presented in halfnote was comparatively simple, its creation shows the possibility for a new breed of web applications that are usable both online and offline.

Reference

The following are global objects that exist as properties of every window object. This means that they can be accessed as sessionStorage or window.sessionStorage. (This is important because you can then use IFrames to store, or access, additional data, beyond what is immediately included in your page.)

Storage

This is a constructor (Storage) for all Storage instances (sessionStorage and globalStorage[location.hostname]).  Setting Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) } would be accessed as localStorage.removeKey and sessionStorage.removeKey.

globalStorage items are not an instance of Storage, but instead are an instance of StorageObsolete.

Storage is defined by the WhatWG Storage Interface as this:

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();
};
Note: Although the values can be set and read using the standard JavaScript property access method, using the getItem and setItem methods is recommended.
Note: Keep in mind that everything you store in any of the storages described in this page is converted to string using its .toString method before being stored. So trying to store a common object will result in string "[object Object]" to be stored instead of the object or its JSON representation. Using native JSON parsing and serialization methods provided by the browser is a good and common way for storing objects in string format.

sessionStorage

This is a global object (sessionStorage) that maintains a storage area that's available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a new session to be initiated.

// Save data to a the current session's store
sessionStorage.setItem("username", "John");

// Access some stored data
alert( "username = " + sessionStorage.getItem("username"));

The sessionStorage object is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed.

{{ fx_minversion_note("3.5", "Prior to Firefox 3.5, sessionStorage data was not restored automatically after recovering from a browser crash.  Starting in Firefox 3.5, this works as per the specification.") }}

Examples:

Autosave the contents of a text field, and if the browser is accidentally refreshed, restore the text field contents, so that no writing is lost.

 // Get the text field that we're going to track
 var field = document.getElementById("field");
 
 // See if we have an autosave value
 // (this will only happen if the page is accidentally refreshed)
 if ( sessionStorage.getItem("autosave")) {
    // Restore the contents of the text field
    field.value = sessionStorage.getItem("autosave");
 }
 
 // Check the contents of the text field every second
 setInterval(function(){
    // And save the results into the session storage object
    sessionStorage.setItem("autosave", field.value);
 }, 1000);

More information:

localStorage

localStorage is the same as sessionStorage with same same-origin rules applied but it is persistent. localStorage was introduced in Firefox 3.5.

Note: When the browser goes into private browsing mode, a new, temporary database is created to store local storage data; this database is emptied, and is thrown away when private browsing mode is turned off.
Compatibility

Storage objects are a recent addition to the standard. As such they may not be present in all browsers. You can work around this by inserting one of the following two codes at the beginning of your scripts, allowing use of localStorage object in implementations which do not natively support it.

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;
  })());
}
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.setItem() and localStorage.removeItem() to add, change or remove a key. The use of methods localStorage.yourKey = yourValue; and delete localStorage.yourKey; to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage document's cookies regardless of the localStorage object.

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8. It also makes use of 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;
}
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem(), localStorage.setItem() and localStorage.removeItem() to get, add, change or remove a key. The use of method localStorage.yourKey in order to get, set or delete a key is not permitted with this code. You can also change its name and use it only to manage document's cookies regardless of the localStorage object.
Compatibility and relation with globalStorage

localStorage is also the same as  globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items, only extending StorageObsolete.prototype does.

globalStorage

{{ obsolete_header() }}globalStorage is unsupported since Gecko 13 (Firefox 13). Just use {{ Anch("localStorage") }} instead. {{ Non-standard_header() }} 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).

Note: globalStorage is not a Storage instance, but a StorageList instance containing StorageObsolete instances.
// Save data that only scripts on the mozilla.org domain can access
globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");

Specifically, the globalStorage object provides access to a number of different storage objects into which data can be stored. For example, if we were to build a web page that used globalStorage on this domain (developer.mozilla.org) we'd have the following storage object available to us:

  • globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }} - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.

{{ Fx_minversion_note("3") }}

Examples:

All of these examples require that you have a script inserted (with each of the following code) in every page that you want to see the result on.

Remember a user's username for the particular sub-domain that is being visited:

 globalStorage['developer.mozilla.org'].setItem("username", "John");

Keep track of the number of times that a user visits all pages of your domain:

 // 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);

Storage location and clearing the data

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 individual cookies (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.

More information

Examples

  • 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.

Browser compatibility

{{ CompatibilityTable() }}

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 {{ CompatNo() }} 2 {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }}
Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}

All browsers have varying capacity levels for both local- and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

 

Related

{{ HTML5ArticleTOC() }}

{{ languages( { "es": "es/DOM/Almacenamiento", "fr": "fr/DOM/Storage", "ja": "ja/DOM/Storage", "pl": "pl/DOM/Storage", "zh-cn": "cn/DOM/Storage" } ) }}

Revision Source

<h3>Summary</h3>
<p>DOM Storage is the name given to the set of <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#storage">storage-related features</a> first introduced in the <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/" title="http://www.whatwg.org/specs/web-apps/current-work/">Web Applications 1.0</a> specification, and now split off into its own <a class="external" href="http://dev.w3.org/html5/webstorage/" title="http://dev.w3.org/html5/webstorage/">W3C Web Storage</a> specification. DOM Storage is designed to provide a larger, more secure, and easier-to-use alternative to storing information in cookies. It was first introduced with <a href="/en/Firefox_2_for_developers" title="en/Firefox_2_for_developers">Firefox 2</a> and <a class="external" href="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html" title="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html">Safari 4</a>.</p>
<div class="note"><strong>Note:</strong> DOM Storage is not the same as <a href="/en/Storage" title="en/Storage">mozStorage</a> (Mozilla's XPCOM interfaces to SQLite) or the <a href="/en/Session_store_API" title="en/Session_store_API">Session store API</a> (an <a href="/en/XPCOM" title="en/XPCOM">XPCOM</a> storage utility for use by extensions).</div>
<h3 id="Description">Description</h3>
<p>The DOM Storage mechanism is a means through which string key/value pairs can be securely stored and later retrieved for use. The goal of this addition is to provide a comprehensive means through which interactive applications can be built (including advanced abilities, such as being able to work "offline" for extended periods of time).</p>
<p>Mozilla-based browsers, Internet Explorer 8+, Safari 4+ and Chrome all provide a working implementation of the DOM Storage specification. (In case you need this functionality cross-browser and you need to cater for older versions of IE, it may be useful to note that Internet Explorer also has a similar legacy feature called "<a class="external" href="http://msdn.microsoft.com/en-us/library/ms531424(VS.85).aspx">userData behavior</a>" that predates the addition of DOM Storage to IE in IE8.)</p>
<p>DOM Storage is useful because no good browser-only methods exist for persisting reasonable amounts of data for any period of time. <a class="external" href="http://en.wikipedia.org/wiki/HTTP_cookie">Browser cookies</a> have limited capacity and provide no support for organizing persisted data, and other methods (such as <a class="external" href="http://www.macromedia.com/support/documentation/en/flashplayer/help/help02.html">Flash Local Storage</a>) require an external plugin.</p>
<p>One of the first public applications to make use of the new DOM Storage functionality (in addition to Internet Explorer's userData Behavior) was <a class="external" href="http://aaronboodman.com/halfnote/">halfnote</a> (a note-taking application) written by <a class="external" href="http://aaronboodman.com/">Aaron Boodman</a>. In his application, Aaron simultaneously saved notes back to a server (when Internet connectivity was available) and a local data store. This allowed the user to safely write backed-up notes even with sporadic Internet connectivity.</p>
<p>While the concept, and implementation, presented in halfnote was comparatively simple, its creation shows the possibility for a new breed of web applications that are usable both online and offline.</p>
<h3>Reference</h3>
<p>The following are global objects that exist as properties of every <a href="/en/DOM/window" title="en/DOM/window"><code>window</code> object</a>. This means that they can be accessed as <code>sessionStorage</code> or <code>window.sessionStorage</code>. (This is important because you can then use IFrames to store, or access, additional data, beyond what is immediately included in your page.)</p>
<h4 id="sessionStorage"><code>Storage</code></h4>
<p>This is a constructor (<code>Storage</code>) for all Storage instances (<code>sessionStorage</code> and <code>globalStorage[location.hostname]).</code>  Setting <code>Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) }</code> would be accessed as <code>localStorage.removeKey and sessionStorage.removeKey</code>.</p>
<p><code>globalStorage</code> items are not an instance of <code>Storage</code>, but instead are an instance of <code>StorageObsolete</code>.</p>
<p><code>Storage</code> is defined by the WhatWG <a class="external" href="http://dev.w3.org/html5/webstorage/#storage-0" title="http://dev.w3.org/html5/webstorage/#storage-0">Storage Interface</a> as this:</p>
<pre class="eval">interface <dfn id="storage-0">Storage</dfn> {
  readonly attribute unsigned long <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-length" title="dom-Storage-length">length</a>;
  [IndexGetter] DOMString <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-key" title="dom-Storage-key">key</a>(in unsigned long index);
  [NameGetter] DOMString <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-getitem" title="dom-Storage-getItem">getItem</a>(in DOMString key);
  [NameSetter] void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-setitem" title="dom-Storage-setItem">setItem</a>(in DOMString key, in DOMString data);
  [NameDeleter] void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-removeitem" title="dom-Storage-removeItem">removeItem</a>(in DOMString key);
  void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-clear" title="dom-Storage-clear">clear</a>();
};
</pre>
<div class="note"><strong>Note: </strong>Although the values can be set and read using the standard JavaScript property access method, using the getItem and setItem methods is recommended.</div>
<div class="note"><strong>Note:</strong> Keep in mind that everything you store in any of the storages described in this page is converted to string using its <code>.toString</code> method before being stored. So trying to store a common object will result in string <code>"[object Object]"</code> to be stored instead of the object or its JSON representation. Using native JSON parsing and serialization methods provided by the browser is a good and common way for storing objects in string format.</div>
<h4 id="sessionStorage"><code>sessionStorage</code></h4>
<p>This is a global object (<code>sessionStorage</code>) that maintains a storage area that's available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a new session to be initiated.</p>
<pre class="brush: js">// Save data to a the current session's store
sessionStorage.setItem("username", "John");

// Access some stored data
alert( "username = " + sessionStorage.getItem("username"));
</pre>
<p>The <code>sessionStorage</code> object is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed.</p>
<p>{{ fx_minversion_note("3.5", "Prior to Firefox 3.5, sessionStorage data was not restored automatically after recovering from a browser crash.  Starting in Firefox 3.5, this works as per the specification.") }}</p>
<p><strong>Examples:</strong></p>
<p>Autosave the contents of a text field, and if the browser is accidentally refreshed, restore the text field contents, so that no writing is lost.</p>
<pre class="brush: js"> // Get the text field that we're going to track
 var field = document.getElementById("field");
 
 // See if we have an autosave value
 // (this will only happen if the page is accidentally refreshed)
 if ( sessionStorage.getItem("autosave")) {
    // Restore the contents of the text field
    field.value = sessionStorage.getItem("autosave");
 }
 
 // Check the contents of the text field every second
 setInterval(function(){
    // And save the results into the session storage object
    sessionStorage.setItem("autosave", field.value);
 }, 1000);
</pre>
<p><strong>More information:</strong></p>
<ul> <li><a class="external" href="http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute" title="http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute">sessionStorage specification</a></li>
</ul>
<h4><code>localStorage</code></h4>
<p><code>localStorage</code> is the same as sessionStorage with same same-origin rules applied but it is persistent. <code>localStorage</code> was introduced in Firefox 3.5.</p>
<div class="note"><strong>Note:</strong> When the browser goes into private browsing mode, a new, temporary database is created to store local storage data; this database is emptied, and is thrown away when private browsing mode is turned off.</div>
<h5>Compatibility</h5>
<p><code>Storage</code> objects are a recent addition to the standard. As such they may not be present in all browsers. You can work around this by inserting one of the following two codes at the beginning of your scripts, allowing use of <code>localStorage</code> object in implementations which do not natively support it.</p>
<p>This algorithm is an exact imitation of the <code>localStorage</code> object, but making use of cookies.</p>
<pre class="brush: js">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 &gt; 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
      for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId &lt; aCouples.length; iCouplId++) {
        iCouple = aCouples[iCouplId].split(/\s*=\s*/);
        if (iCouple.length &gt; 1) {
          oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
          aKeys.push(iKey);
        }
      }
      return oStorage;
    };
    this.configurable = false;
    this.enumerable = true;
  })());
}
</pre>
<div class="note"><strong>Note:</strong> The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions <code>localStorage.setItem()</code> and <code>localStorage.removeItem()</code> to add, change or remove a key. The use of methods <code>localStorage.yourKey = yourValue;</code> and <code>delete localStorage.yourKey;</code> to set or delete a key <strong>is not a secure way with this code</strong>. You can also change its name and use it only to manage document's cookies regardless of the localStorage object.</div>
<p>Here is another, less exact, imitation of the <code>localStorage</code> object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer &lt; 8. It also makes use of cookies.</p>
<pre class="brush: js">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, "\\$&amp;") + "\\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, "\\$&amp;") + "\\s*\\=")).test(document.cookie); }
  };
  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
}
</pre>
<div class="note"><strong>Note:</strong> The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions <code>localStorage.getItem()</code>, <code>localStorage.setItem()</code> and <code>localStorage.removeItem()</code> to get, add, change or remove a key. The use of method <code>localStorage.yourKey</code> in order to get, set or delete a key <strong>is not permitted with this code</strong>. You can also change its name and use it only to manage document's cookies regardless of the localStorage object.</div>
<h5 id="localStorage_compatibility">Compatibility and relation with globalStorage</h5>
<p class="note"><code>localStorage</code> is also the same as  <code>globalStorage[location.hostname]</code>, with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and <code>localStorage</code> being an instance of <code>Storage</code> as opposed to <code>globalStorage[location.hostname]</code> being an instance of <code>StorageObsolete</code> which is covered below. For example, <a class=" external" href="http://example.com" rel="freelink">http://example.com</a> is not able to access the same <code>localStorage</code> object as <a class=" link-https" href="https://example.com" rel="freelink">https://example.com</a> but they can access the same <code>globalStorage</code> item. <code>localStorage</code> is a standard interface while <code>globalStorage</code> is non-standard so you shouldn't rely on these.</p>
<p>Please note that setting a property on <code>globalStorage[location.hostname]</code> does <strong>not</strong> set it on <code>localStorage</code> and extending <code>Storage.prototype</code> does not affect <code>globalStorage</code> items, only extending <code>StorageObsolete.prototype</code> does.</p>
<h4><code>globalStorage</code></h4>
<p>{{ obsolete_header() }}<code>globalStorage </code>is unsupported since Gecko 13 (Firefox 13). Just use<code> {{ Anch("localStorage") }} </code>instead. {{ Non-standard_header() }} This is a global object (<code>globalStorage</code>) 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).</p>
<div class="warning">Note: <code>globalStorage</code> is not a <code>Storage</code> instance, but a <code>StorageList</code> instance containing <code>StorageObsolete</code> instances.</div>
<pre class="eval deki-transform">// Save data that only scripts on the mozilla.org domain can access
globalStorage['mozilla.org'].setItem("snippet", "&lt;b&gt;Hello&lt;/b&gt;, how are you?");
</pre>
<p>Specifically, the <code>globalStorage</code> object provides access to a number of different storage objects into which data can be stored. For example, if we were to build a web page that used <code>globalStorage</code> on this domain (developer.mozilla.org) we'd have the following storage object available to us:</p>
<ul> <li><code>globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }}</code> - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.</li>
</ul>
<p>{{ Fx_minversion_note("3") }}</p>
<p><strong>Examples:</strong></p>
<p>All of these examples require that you have a script inserted (with each of the following code) in every page that you want to see the result on.</p>
<p>Remember a user's username for the particular sub-domain that is being visited:</p>
<pre class="eval deki-transform"> globalStorage['developer.mozilla.org'].setItem("username", "John");
</pre>
<p>Keep track of the number of times that a user visits all pages of your domain:</p>
<pre class="eval deki-transform"> // 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);
</pre>
<h3>Storage location and clearing the data</h3>
<p>In Firefox the DOM storage data is stored in the <a class="external" href="http://kb.mozillazine.org/Webappsstore.sqlite" title="http://kb.mozillazine.org/Webappsstore.sqlite">webappsstore.sqlite file</a> in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=592990" title="https://bugzilla.mozilla.org/show_bug.cgi?id=592990">notably for the start page - about:home</a>, but potentially for other internal pages with "about:" URLs).</p>
<ul> <li>DOM Storage can be cleared via "Tools -&gt; Clear Recent History -&gt; Cookies" when Time range is "Everything" (via nsICookieManager::removeAll) <ul> <li>But not when another time range is specified: (<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=527667" title="https://bugzilla.mozilla.org/show_bug.cgi?id=527667">bug 527667</a>)</li> <li>Does not show up in Tools -&gt; Options -&gt; Privacy -&gt; Remove individual cookies (<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=506692" title="https://bugzilla.mozilla.org/show_bug.cgi?id=506692">bug 506692</a>)</li> </ul> </li> <li>DOM Storage is <strong>not</strong> cleared via Tools -&gt; Options -&gt; Advanced -&gt; Network -&gt; Offline data -&gt; Clear Now.</li> <li>Doesn't show up in the "Tools -&gt; Options -&gt; Advanced -&gt; Network -&gt; 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 <a href="/en/Using_the_Application_Cache" title="en/Offline resources in Firefox">offline cache</a> when clicking the Remove button.</li>
</ul>
<p>See also <a href="/en/Using_the_Application_Cache#Storage_location_and_clearing_the_offline_cache" title="en/Offline resources in Firefox#Storage location and clearing the offline cache">clearing offline resources cache</a>.</p>
<h3 id="More_information">More information</h3>
<ul> <li><a class="external" href="http://www.w3.org/TR/webstorage/" title="http://www.w3.org/TR/webstorage/">Web Storage</a> (W3C Web Apps Working Group)</li> <li><a class="external" href="http://kb.mozillazine.org/Dom.storage.enabled">Enable/Disable DOM Storage in Firefox or SeaMonkey</a></li>
</ul>
<h3>Examples</h3>
<ul> <li><a class="external" href="http://www.diveintojavascript.com/tutorials/web-storage-tutorial-creating-an-address-book-application" title="JavaScript Web Storage Tutorial: Creating an Address Book Application">JavaScript Web Storage Tutorial: Creating an Address Book Application</a> - hands-on tutorial describing how to use the Web Storage API by creating a simple address book application</li> <li><a class="external" href="http://hacks.mozilla.org/2010/01/offline-web-applications/" title="http://hacks.mozilla.org/2010/01/offline-web-applications/">offline web applications</a> at hacks.mozilla.org - showcases an offline app demo and explains how it works.</li> <li><a class="external" href="http://noteboard.eligrey.com/" title="http://noteboard.eligrey.com/">Noteboard</a> - Note writing application that stores all data locally.</li> <li><a class="external" href="http://github.com/eligrey/jData-host" title="http://github.com/eligrey/jData-host">jData</a> - 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.</li> <li><a class="external" href="http://codebase.es/test/webstorage.html" title="http://codebase.es/test/webstorage.html">HTML 5 localStorage example</a>. 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.</li> <li><a class="external" href="http://upload.jonathanwilsson.com/html5/sessionstorage.php" title="http://upload.jonathanwilsson.com/html5/sessionstorage.php">HTML5 Session Storage</a>. A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.</li> <li><a class="external" href="http://channy.creation.net/work/firefox/domstorage/"><strike>Basic DOMStorage Examples</strike></a><strike> - 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.</strike></li> <li><a class="external" href="http://aaronboodman.com/halfnote/"><strike>halfnote</strike></a><strike> - (displaying broken in Firefox 3) Note writing application that uses DOM Storage.</strike></li>
</ul>
<h3>Browser compatibility</h3>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop"> <table class="compat-table"> <tbody> <tr> <th>Feature</th> <th>Chrome</th> <th>Firefox (Gecko)</th> <th>Internet Explorer</th> <th>Opera</th> <th>Safari (WebKit)</th> </tr> <tr> <td>localStorage</td> <td>4</td> <td>3.5</td> <td>8</td> <td>10.50</td> <td>4</td> </tr> <tr> <td>sessionStorage</td> <td>5</td> <td>2</td> <td>8</td> <td>10.50</td> <td>4</td> </tr> <tr> <td>globalStorage</td> <td>{{ CompatNo() }}</td> <td>2</td> <td>{{ CompatNo() }}</td> <td>{{ CompatNo() }}</td> <td>{{ CompatNo() }}</td> </tr> </tbody> </table>
</div>
<div id="compat-mobile"> <table class="compat-table"> <tbody> <tr> <th>Feature</th> <th>Android</th> <th>Firefox Mobile (Gecko)</th> <th>IE Phone</th> <th>Opera Mobile</th> <th>Safari Mobile</th> </tr> <tr> <td>Basic support</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> <td>{{ CompatUnknown() }}</td> </tr> </tbody> </table>
</div>
<p>All browsers have varying capacity levels for both local- and sessionStorage. Here is a <a class="external" href="http://dev-test.nemikor.com/web-storage/support-test/" title="http://dev-test.nemikor.com/web-storage/support-test/">detailed rundown of all the storage capacities for various browsers</a>.</p>
<p> </p>
<h3>Related</h3>
<ul> <li><a class="external" href="http://en.wikipedia.org/wiki/HTTP_cookie">HTTP cookies</a> (<code><a href="/en/DOM/document.cookie" title="en/DOM/document.cookie">document.cookie</a></code>)</li> <li><a class="external" href="http://www.macromedia.com/support/documentation/en/flashplayer/help/help02.html">Flash Local Storage</a></li> <li><a class="external" href="http://msdn2.microsoft.com/en-us/library/ms531424.aspx">Internet Explorer userData behavior</a></li> <li><a href="/en/XPCOM_Interface_Reference/nsIDOMStorageEventObsolete" title="en/XPCOM Interface Reference/nsIDOMStorageEventObsolete">nsIDOMStorageEventObsolete</a></li> <li><a href="/en/DOM/event/StorageEvent" title="en/DOM/Event/StorageEvent">StorageEvent</a></li>
</ul>
<p>{{ HTML5ArticleTOC() }}</p>
<p>{{ languages( { "es": "es/DOM/Almacenamiento", "fr": "fr/DOM/Storage", "ja": "ja/DOM/Storage", "pl": "pl/DOM/Storage", "zh-cn": "cn/DOM/Storage" } ) }}</p>
Revert to this revision