Almacenamiento

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 .

Nota: el almacenamiento DOM no es lo mismo que mozStorage (las interfaces XPCOM de Mozilla para SQLite) o la API para guardar sesiones (una utilidad de almacenamiento XPCOM usada por extensiones).

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();
};

 

Nota: aunque los valores pueden establecerse y leerse a través del método de acceso de la propiedad de JavaScript estándar, se recomienda el uso de los métodos getItem y setItem.
Nota: ten en cuenta que todo lo que guardes en cualquiera de los almacenamientos (storages) descritos en esta página se convierte en una cadena a través de su método .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.

Nota sobre Firefox 3.5

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.

Este es un objeto global ( 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) .

Nota: 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.

Nota sobre Firefox 3

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, http://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.

Nota: cuando el navegador entra en modo de navegación privada, se crea una nueva base de datos temporal para almacenar los datos locales de almacenamiento; esta base de datos se vacía cuando se sale del modo de navegación privada.
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;
  })());
}
Nota: el tamaño máximo de datos que pueden guardarse está bastante restringido por el uso de cookies. Con este algoritmo, usa las funciones 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;
}
Nota: el tamaño máximo de datos que pueden guardarse está bastante restringido por el uso de cookies. Con este algoritmo, usa las funciones 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

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

 

 

Etiquetas y colaboradores del documento

Última actualización por: AshfaqHossain,