Hablaba el pasado día cinco sobre la abstracción que realiza Sencha Touch sobre las propiedades de almacenamiento web presentes en la especificación de HTML5. Hoy vamos a conocer como funcionan esos almacenamientos directamente en esta introducción al almacenamiento de variables en el cliente con HTML5.
El almacenamiento web está ampliamente soportado por los navegadores modernos, tanto en plataforma escritorio como en plataforma móvil, Android 2.1+, iPhone 3.1+, iPad 4.2+, Opera Mobile 11.00+, Palm WebOS 1.4+ y BlackBerry 6.0+ soportan el almacenamiento web sin problemas.
En cuanto a plataforma de escritorio, Crome 4.0+, Firefox 3.5+, IE 8.0+, Opera 10.5+ y Safari 4.0+ soportan esta feature sin problemas. La única diferencia consiste en la cantidad o peso de los datos que cada uno de ellos puede guardar en cada tipo de almacenamiento siendo Firefox e IE los que más cantidad de datos permiten almacenar
W3C Web Storage
La espcificación de la W3C para el almacenamiento web ha sido diseñada para proveer de una forma mejor y más segura de almacenar información que el método tradicional de almacenamiento en cookies. Además el Web Storage ofrece mayor capacidad de almacenamiento por dominio y una mejor interfaz de acceso a los datos.
Interfaz del lado cliente
A diferencia del mecanismo implementado en las cookies a las que tanto el cliente como el servidor tienen acceso, en el almacenamiento web, solo el cliente tiene acceso a los datos. Los datos por tanto no son enviados hacia el servidor en cada consulta HTTP, pero el servidor puede hacer peticiones al cliente para recibir los datos que requiera.
Tipos de almacenamiento
El almacenamiento web ofrece dos áreas de almacenamiento diferentes, el almacenamiento local y el almacenamiento por sesión, que difieren en alcance y tiempo de vida. Mozilla también ofrece otro tipo de almacenamiento al que ellos llaman global del que no voy a mencionar nada más ya que no es parte del estándar.
Los datos alojados en un almacenamiento local es solo accesible por dominio y persiste aún cuando se cierre el navegador. El almacenamiento por sesión es por ventana y su tiempo de vida está limitado a lo que dure la ventana (o pestaña). Con el almacenamiento por sesión lo que se persigue es la posibilidad de que separar instancias de la misma aplicación web para que puedan ejecutarse en diferentes ventanas (o pestañas) sin que interfieran entre ellas.
Los datos son almacenados usando pares de clave/valor. Se supone que las aplicaciones web que utilicen esta tecnología son capaces de trabajar offline por largos periodos de tiempo
Versiones anteriores de Internet Explorer
En versiones anteriores de Internet Explorer a la versión 8, se puede utilizar un mecanismo similar llamado userData que no pertenece al estándar y del que tampoco voy a hablar en este artículo, pero dejo un enlace a su especificación para que quien quiera pueda echarle un vistazo.
También se puede usar Flash Local Storage con el plugin de flash para dar soporte a IE 6 y 7 pero me parece bastante estúpido usar flash cuando Microsoft ya nos provee de otro método nativo.
sessionStorage
Objeto global que mantiene un área de almacenamiento disponible a lo largo de la duración de la sesión de la página, ventana o pestaña. La sesión persiste mientras que la ventana permanezca abierta y sobrevive a recargas de página. Si se abre una nueva página en una pestaña o ventana, una nueva sesión es inicializada.
// Guardamos el nombre del editor en el almacén de la sesión actual
sessionStorage.setItem("editor", "Oscar Campos");
// Accedemos a los datos almacenados
alert("El editor es "+ sessionStorage.getItem("editor"));
La mayoría del tiempo los sessionStorage
son útiles a la hora de guardar datos temporales que deben ser persistentes en caso de que el navegador se refresque.
Esto es muy útil por ejemplo en un formulario de edición de posts en un blog donde si por casualidad pulsamos la tecla F5 el navegador se refresca y perdemos todo nuestro post después de una hora de trabajo (basado en hechos reales):
// Obtenemos el elemento que contiene el contenido del post
var content = document.getElementById("content");
// Comprobamos si existe contenido guardado
// lo cual indicaría un refresco de página accidental
if (sessionStorage.getItem("autosave")) {
content.value = sessionStorage.getItem("autosave");
}
// Guardamos el contenido del elemento cada minuto
setInterval(function() {
sessionStorage.setItem("autosave", content.value);
}, 1000*60);
Una forma sencilla de hacer más feliz y tranquila la vida de los editores de blogs.
localStorage
Los almacenes locales funcionan de la misma forma que los almacenes de sesión con la excepción de que son capaces de almacenar los datos por dominio y mantener persistencia más allá de la sesión actual e incluso de que el navegador completo sea cerrado. En algunos casos como en el de IE8 puede llegar a guardar hasta 10MB de información, si lo comparamos con las 4k de una cookie nos entra la risa floja.
El uso es muy similar al del sessionStorage
, solo debemos añadir el dominio con el que vamos a trabajar:
localStorage['www.genbetadev.com'].setItem("editor", "Oscar Campos");
Podemos hacer cosas más complejas como almacenar el número de veces que un usuario ha visitado una página:localStorage['www.genbetadev.com'].setItem("visitas", parseInt(localStorage['www.gebetadev.com'].getItem("visitas") || 0 ) + 1);
IndexedDB/Web SQL Database
Web SQL Database esta abandonado y no se va a seguir desarrollando su especificación por lo que no voy a hablar sobre él. Aunque estaba ampliamente soportado, al estar abandonado su soporte puede ser abandonado por los fabricantes en cualquier momento por lo que su uso está completamente desaconsejado, solo lo menciono aquí por razones históricas.
IndexedDB es una API para almacenamiento avanzado de datos en la parte cliente y pretende servir como mecanismo de almacenamiento de grandes cantidades de datos estructurados que además nos provea de un acceso de alto rendimiento a los mismos usando índices. Mientras que el Web Storage nos es treméndamente útil para almacenar pequeñas cantidades de datos, IndexedDB nos es útil para almacenar grandes cantidades de datos complejos y estructurados.
IndexedDB provee de una API para consultas asíncronas separada de la API de consultas síncronas. Provee de transacciones y aunque solo está soportada de momento por Chrome 11+ y Firefox 4+ todos los fabricantes han prometido implementarlo en sus productos por lo que en breve esperamos que este completamente soportado.
Los conceptos básicos a entender sobre IndexedDB son los siguientes:
Almacena pares de clave/valor. Los valores pueden ser estructuras complejas de objetos y las claves propiedades de dichos objetos. Los índices pueden usar cualquier propiedad de los objetos para proporcionar búsquedas rápidas y enumeraciones.
Esta construido sobre un modelo de base de datos transaccional. Todo lo que hagas en IndexedDB ocurre en el contexto de una transacción.
Su API es mayormente asíncrona. La API no te ofrece acceso a sus datos devolviéndote valores, sino que debes de proporcionar un callback que será disparado cuando haya un valor que devolver. (Recuerda mi introducción a la programación dirigida por eventos).
Esta orientada a objetos. IndexedDB no es una base de datos relacional sino una base de datos orientada a objetos.
No usa (SQL). Usa consultas en un índice que producen un cursor.
Usa eventos DOM para notificar cuando los resultados de una consulta están disponibles. Y como todo evento puede ser escuchado y procesado por manejadores especializados.
No voy a entrar en demasiado detalle sobre el uso de este tipo de almacenamiento en la parte cliente sobre todo por que mis conocimientos sobre el mismo son hoy por hoy bastante limitados, pero prometo hacer una entrada mucho más profunda sobre el asunto en el futuro donde también hablaré sobre el AppStore. Hasta entonces, happy coding.
Más en Genbeta Dev | Introducción a HTML5
Más Información | Working Draft de webstorage de la W3C, Working Draft de IndexedDB de la W3C