Introducción
El almacenamiento DOM (DOM Storage) es el nombre dado al conjunto de características relacionadas con el almacenamiento introducidas en la especificación de aplicaciones web 1.0 y ahora detalladas por separado en su propia especificación W3C Web Storage. El almacenamiento DOM está diseñado para facilitar una forma amplia, segura y sencilla para almacenar información alternativa a las cookies. Fue introducido por primera vez en Firefox 2 y Safari 4 .
Descripción
El mecanismo de almacenamiento DOM es el medio a través del cual pares de clave/valor pueden ser almacenadas de forma segura para ser recuperadas y utilizadas más adelante. La meta de este añadido es suministrar un método exhaustivo a través del cual puedan construirse aplicaciones interactivas (incluyendo características avanzadas tales como ser capaces de trabajar "sin conexión" durante largos períodos de tiempo).
Actualmente los navegadores basados en Mozilla, Internet Explorer 8+ y Safari 4 y Chrome proporcionan una implementación funcional de la especificación del almacenamiento DOM. Sin embargo, las versiones anteriores a Internet Explorer 8 poseen una característica similar llamada "userData behavior" que permite conservar datos entre múltiples sesiones.
El almacenamiento DOM es útil ya que ningún navegador dispone de buenos métodos para conservar cantidades razonables de datos durante un periodo de tiempo. Las cookies de los navegadores tienen una capacidad limitada y no implementan una forma de organizar datos persistentes y otros métodos (tales como almacenamiento local de Flash) necesitan un plugin externo.
Una de las primeras aplicaciones hechas públicas que hace uso de la nueva funcionalidad de almacenamiento DOM (además del userData Behavior de Internet Explorer) fue halfnote (una aplicación para tomar notas) escrita por Aaron Boodman. En su aplicación, Aaron enviaba notas hacia el servidor (cuando la conexión a Internet estaba disponible) y simultáneamente las guardaba en local. Esto permitía al usuario escribir notas de modo seguro incluso cuando no disponía de conexión a Internet.
Aunque el concepto e implementación presentada en halfnote era en comparación simple, su creación mostró las posibilidades de esta nueva generación de aplicaciones web utilizables tanto con conexión como sin ella.
Referencia
Los siguientes objetos globales existen como propiedades de cada objeto window
. Esto significa que se puede acceder a ellas como sessionStorage
o window.sessionStorage
(esto es importante ya que se puede usar IFrames para almacenar o acceder a datos adicionales, más allá de lo que está inmediatamente incluido en la página).
Storage
Este es un constructor ( Storage
) para todos los objetos de almacenamiento ( sessionStorage
y globalStorage[location.hostname]).
Al hacer Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) }
podrías usar luego como atajo a la función removeItem("key")
la forma localStorage.removeKey and sessionStorage.removeKey
.
Los elementos globalStorage
no son de tipo Storage
, sino StorageObsolete
.
Storage
se define por la interfaz de almacenamiento WhatWG de la siguiente forma:
interface Storage { readonly attribute unsigned long length; [IndexGetter]key DOMString (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
almacenado anteriormente, por lo que al intentar almacenar un objeto común, se almacenará una cadena "[object Object]"
en lugar del objeto o su representación JSON. Usar los métodos de serialización y análisis de JSON nativos que proporciona el navegador es una buena forma bastante común de almacenar objetos en formato cadena.sessionStorage
Este es un objeto global (sessionStorage
) que mantiene un área de almacenamiento que está disponible durante la sesión de página. Una sesión de página existe mientras el navegador esté abierto y sobrevive a recargas o restauraciones de páginas. Abrir una página en una nueva pestaña o en una ventana provoca que se cree una nueva sesión.
// Guardar datos en el almacén de la sesión actual sessionStorage.setItem("username", "John"); // Acceder a algunos datos guardados alert( "username = " + sessionStorage.getItem("username"));
El objeto sessionStorage
es más usado para manejar datos temporales que deberían ser guardados y recuperados si el navegador es recargado accidentalmente.
Antes de Firefox 3.5, los datos de sessionStorage no se restablecían automáticamente después de recuperarse de un fallo del navegador. A partir de Firefox 3.5, funciona según la especificación.
Ejemplos:
Autoguardado de los contenidos de un campo de texto y, si el navegador se recarga accidentalmente, restauración del contenido del campo de texto para evitar la pérdida de datos.
// Obtener el campo de texto al que vamos a seguir la pista var field = document.getElementById("field"); // Ver si se tiene un valor de autoguardado // (esto sólo sucede si la página es actualizada accidentalmente) if ( sessionStorage.getItem("autosave")) { // Restaurar los contenidos del campo de texto field.value = sessionStorage.getItem("autosave"); } // Comprobar los contenidos del campo de texto cada segundo setInterval(function(){ // Y guardar los resultados en el objeto de almacenamiento de sesión sessionStorage.setItem("autosave", field.value); }, 1000);
Más información:
globalStorage
No estándar
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
globalStorage
) que mantiene múltiples áreas de almacenamiento privado que se pueden utilizar para almacenar los datos durante un largo período de tiempo (por ejemplo, en varias páginas y las sesiones del navegador) .
globalStorage
no es de tipo Storage
, sino un objeto de tipo StorageList
que contiene a su vez elementos StorageObsolete
.// Guardar datos a los que sólo pueden acceder scripts del dominio mozilla.org globalStorage['mozilla.org'].setItem("snippet", "<b>Hola</b>, ¿cómo estás?");
Específicamente, el objeto globalStorage
proporciona acceso a un número de diferentes objetos de almacenamiento en los que los datos pueden ser guardados. Por ejemplo, si se construye una página web que usa globalStorage
en este dominio (developer.mozilla.org) se dispondría de los siguientes objetos de almacenamiento:
globalStorage['developer.mozilla.org']
- Todas las páginas web dentro del subdominio developer.mozilla.org podrán leer de, y escribir datos en, este objeto de almacenamiento.
Firefox 2 permitía el acceso a objetos de almacenamiento superiores en la jerarquía del dominio al documento actual, pero esto ya no se permite en Firefox 3 por razones de seguridad. Además, se ha eliminado esta adición propuesta a HTML 5 de la especificación en favor de localStorage
, que se implementa a partir de Firefox 3.5.
Ejemplos:
Todos estos ejemplos necesitan que haya un script insertado (con el siguiente código) en cada página en la que se quiera ver el resultado.
Recordar el nombre un usuario para un subdominio en particular que está siendo visitado:
globalStorage['developer.mozilla.org'].setItem("username", "John");
Seguir la pista al número de veces que un usuario visita todas las páginas de un dominio:
// 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);
localStorage
localStorage
es lo mismo que globalStorage[location.hostname]
, excepto que está dentro del ámbito de un origen HTML5 (esquema + nombre de servidor + puerto no estándar), y que localStorage
es un elemento de tipo Storage
a diferencia de globalStorage[location.hostname]
, que es de tipo StorageObsolete
. Por ejemplo, https://example.com no es capaz de acceder al mismo objeto localStorage
que https://example.com pero pueden acceder al mismo objeto globalStorage
. localStorage
es una interfaz estándar, mientras que globalStorage
no es estándar. localStorage
fue introducida en Firefox 3.5.
Ten en cuenta que establecer una propiedad en globalStorage[location.hostname]
no la establece en localStorage
y extender Storage.prototype
no afecta a los elementos globalStorage
. Esto sólo se hace extendiendo StorageObsolete.prototype
.
Compatibilidad
Los objetos Storage
se han agregado recientemente al estándar, por lo que puede ocurrir que no estén presentes en todos los navegadores. Puedes solucionar esto insertando uno de los siguientes códigos al principio de tus scripts, lo que permitirá el uso del objeto localStorage
object en aquellas implementaciones que de forma nativa no lo admitan.
Este algoritmo es una imitación exacta del objeto localStorage
, pero haciendo uso de 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()
y localStorage.removeItem()
para agregar, cambiar o eliminar una clave. Usar los métodos localStorage.tuClave = tuValor;
y delete localStorage.tuClave;
para establecer o eliminar una clave no es muy seguro con este código. También puedes cambiar su nombre y usarlo para administrar las cookies de un documento independientemente del objeto localStorage.Aquí tienes otra imitación, menos exacta, del objeto localStorage
. Es mucho más simple que el anterior, pero es compatible con los navegadores antiguos como Internet Explorer < 8. También usa 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; }
localStorage.getItem()
, localStorage.setItem()
y localStorage.removeItem()
para agregar, cambiar o eliminar una clave. Usar los métodos localStorage.tuClave
para obtener, establecer o eliminar una clave no es muy seguro con este código. También puedes cambiar su nombre y usarlo para administrar las cookies de un documento independientemente del objeto localStorage.Lugar de almacenamiento y borrado de datos
Los datos de almacenamiento DOM se guardan en el archivo webappsstore.sqlite de la carpeta del perfil.
- Almacenamiento DOM se puede borrar a través de "Herramientas -> Borrar Historial reciente -> Cookies" cuando el rango de tiempo es "Todo" (a través de nsICookieManager:: removeAll)
- Pero no cuando se especifica otro intervalo de tiempo: ( bug 527667 )
- No aparece en Herramientas -> Opciones -> Privacidad -> Eliminar cookies individuales ( bug 506692 )
- El almacenamiento DOM no se elimina a través de Herramientas -> Opciones -> Avanzado -> Red -> Datos en modo sin conexión -> Limpiar ahora.
- No aparece en la lista "Herramientas -> Opciones -> Avanzado -> Red -> Datos en modo sin conexión", a menos que el sitio también utilice la caché sin conexión. Si el sitio aparece en esa lista, los datos de almacenamiento DOM se eliminan junto con la memoria caché sin conexión cuando se hace clic en el botón Eliminar.
Consulta también borrar la caché de recursos en modo sin conexión .
Más información
- Almacenamiento web (W3C Web Grupo de trabajo sobre aplicaciones web)
- Activar / Desactivar almacenamiento DOM en Firefox o SeaMonkey
Ejemplos
- Tutorial de almacenamiento web JavaScript: cómo crear una aplicación de la libreta de direcciones. Práctico tutorial que describe cómo utilizar la API de almacenamiento web mediante la creación de una aplicación sencilla de la libreta de direcciones.
- Aplicaciones web en modo desconexión en hacks.mozilla.org: muestra una demo de la aplicación en modo desconexión y explica cómo funciona.
- Noteboard: aplicación para escritura de notas que almacena todos los datos en local.
- JData: una interfaz de objetos compartidos localStorage a la que cualquier sitio web en Internet puede acceder y que funciona en Firefox 3 +, Webkit 3.1.2 + versiones estables ("nightlies) y IE8. Piensa en ella como pseudo-globalStorage [""], pero el acceso de escritura necesita la confirmación del usuario.
- Ejemplo de localStorage en HTML 5 . Un ejemplo de localStorage muy sencillo y fácil de entender. Guarda y recupera los textos y muestra una lista de elementos guardados. Probado en Firefox 3 o superior.
- Almacenamiento de sesión en HTML5. Un ejemplo muy simple de almacenamiento de sesión. También incluye un ejemplo en almacenamiento local. Probado en Firefox 3.6 o superior.
Compatibilidad de los navegadores
Característica | 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 | Not supported | Not supported | Not supported |
Característica | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Compatibilidad básica | ? | ? | ? | ? | ? |
Todos los navegadores tienen diferentes niveles de capacidad tanto para local- como para sessionStorage. Aquí puedes ver un resumen detallado de todas las capacidades de almacenamiento de los distintos navegadores.
Contenido relacionado
- Cookies HTTP (
document.cookie
) - Almacenamiento local de Flash
- Comportamiento userData en Internet Explorer
- nsIDOMStorageEventObsolete
- StorageEvent