Capítulo 10 API Web Storage

Capítulo 10 API Web Storage

10.1   Dos sistemas de almacenamiento

La Web fue primero pensada como una forma de mostrar información, solo mostrarla. El procesamiento de información comenzó luego, primero con aplicaciones del lado del servidor y más tarde, de forma bastante ineficiente, a través de pequeños códigos y complementos (plug-ins) ejecutados en el ordenador del usuario. Sin embargo, la esencia de la Web siguió siendo básicamente la misma: la información era preparada en el servidor y luego mostrada a los usuarios. El trabajo duro se desarrollaba casi completamente del lado del servidor porque el sistema no aprovechaba los recursos en los ordenadores de los usuarios.

HTML5 equilibra esta situación. Justificada por las particulares características de los dispositivos móviles, el surgimiento de los sistemas de computación en la nube, y la necesidad de estandarizar tecnologías e innovaciones introducidas por plug-ins a través de los últimos años, la especificación de HTML5 incluye herramientas que hacen posible construir y ejecutar aplicaciones completamente funcionales en el ordenador del usuario, incluso cuando no existe conexión a la red disponible.

Una de las características más necesitadas en cualquier aplicación es la posibilidad de almacenar datos para disponer de ellos cuando sean necesarios, pero no existía aún un mecanismo efectivo para este fin. Las llamadas «Cookies» (archivos de texto almacenados en el ordenador del usuario) fueron usadas por años para preservar información, pero debido a su naturaleza se encontraron siempre limitadas a pequeñas cadenas de texto, lo que las hacía útiles solo en determinadas circunstancias.

La API Web Storage es básicamente una mejora de las Cookies. Esta API nos permite almacenar datos en el disco duro del usuario y utilizarlos luego del mismo modo que lo haría una aplicación de escritorio. El proceso de almacenamiento provisto por esta API puede ser utilizado en dos situaciones particulares: cuando la información tiene que estar disponible solo durante la sesión en uso, y cuando tiene que ser preservada todo el tiempo que el usuario desee. Para hacer estos métodos más claros y comprensibles para los desarrolladores, la API fue dividida en dos partes llamadas sessionStorage y localStorage.Devonn

sessionStorage Este es un mecanismo de almacenamiento que conservará los datos disponible solo durante la duración de la sesión de una página. De hecho, a diferencia de sesiones reales, la información almacenada a través de este mecanismo es solo accesible desde una única ventana o pestaña y es preservada hasta que la ventana es cerrada. La especificación aún nombra «sesiones» debido a que la información es preservada incluso cuando la ventana es actualizada o una nueva página desde el mismo sitio web es cargada.

localStorage Este mecanismo trabaja de forma similar a un sistema de almacenamiento para aplicaciones de escritorio. Los datos son grabados de forma permanente y se encuentran siempre disponibles para la aplicación que los creó.

Ambos mecanismos trabajan a través de la misma interface, compartiendo los mismos métodos y propiedades. Y ambos son dependientes del origen, lo que quiere decir que la información está disponible solo a través del sitio web o la aplicación que los creó. Cada sitio web tendrá designado su propio espacio de almacenamiento que durará hasta que la ventana es cerrada o será permanente, de acuerdo al mecanismo utilizado.

La API claramente diferencia datos temporarios de permanentes, facilitando la construcción de pequeñas aplicaciones que necesitan preservar solo unas cadenas de texto como referencia temporaria (por ejemplo, carros de compra) o aplicaciones más grandes y complejas que necesitan almacenar documentos completos por todo el tiempo que sea necesario.

IMPORTANTE: Muchos navegadores solo trabajan de forma adecuada con esta API cuando la fuente es un servidor real. Para probar los siguientes códigos, le recomendamos que primero suba los archivos a su servidor.

10.2   La sessionStorage

Esta parte de la API, sessionStorage, es como un reemplazo para las Cookies de sesión. Las Cookies, así como sessionStorage, mantienen los datos disponibles durante un período específico de tiempo, pero mientras las Cookies de sesión usan el navegador como referencia, sessionStorage usa solo una simple ventana o pestaña. Esto significa que las Cookies creadas para una sesión estarán disponibles mientras el navegador continúe abierto, mientras que los datos creados con sessionStorage estarán solo disponibles mientras la ventana que los creó no es cerrada.

Implementación de un sistema de almacenamiento de datos

Debido a que ambos sistemas, sessionStorage y localStorage, trabajan con la misma interface, vamos a necesitar solo un documento HTML y un simple formulario para probar los códigos y experimentar con esta API:

<!DOCTYPE html>

<html lang=»es»>

<head>

<title>Web Storage API</title>

<link rel=»stylesheet» href=»storage.css»>

<script src=»storage.js»></script>

</head>

<body>

<section id=»cajaformulario»>

<form name=»formulario»>

<p>Clave:<br><input type=»text» name=»clave» id=»clave»></p> <p>Valor:<br><textarea name=»text» id=»texto»></textarea></p> <p><input type=»button» name=»grabar» id=»grabar»

value=»Grabar»></p>

</form>

</section>

<section id=»cajadatos»>

No hay información disponible </section>

</body>

</html>

Listado 10-1. Plantilla para la API Storage

También crearemos un grupo de reglas de estilo simples para dar forma a la página y diferenciar el área del formulario de la caja donde los datos serán mostrados y listados:

#caj aformulario{

float: left;

padding: 20px;

border: 1px solid #999999;

}

#caj adatos{

float: left;

width: 400px;

margin-left: 20px;

padding: 20px;

border: 1px solid #999999;

}

#clave, #texto{

width: 200px;

}

#cajadatos > div{
padding: 5px;

border-bottom: 1px solid #999999;

}

Listado 10-2. Estilos para nuestra plantilla.

Hágalo usted mismo: Cree un archivo HTML con el código del Listado 10-1 y un archivo CSS llamado storage.css con los estilos del Listado 10-2. También necesitará crear un archivo llamado storage.js para grabar y probar los códigos JavaScript presentados a continuación.

Creando datos

Ambos, sessionStorage y localstorage, almacenan datos como ítems. Los ítems están formados por un par clave/valor, y cada valor será convertido en una cadena de texto antes de ser almacenado. Piense en ítems como si fueran variables, con un nombre y un valor, que pueden ser creadas, modificadas o eliminadas.

Existen dos nuevos métodos específicos de esta API incluidos para crear y leer un valor en el espacio de almacenamiento:

setItem(clave, valor) Este es el método que tenemos que llamar para crear un ítem. El ítem será creado con una clave y un valor de acuerdo a los atributos especificados. Si ya existe un ítem con la misma clave, será actualizado al nuevo valor, por lo que este método puede utilizarse también para modificar datos previos. getItem(clave) Para obtener el valor de un ítem, debemos llamar a este método especificando la clave del ítem que queremos leer. La clave en este caso es la misma que declaramos cuando creamos al ítem con setitem().

function iniciar(){

var boton=document.getElementByld(‘grabar’);

boton.addEventListener(‘click’, nuevoitem, false);

}

function nuevoitem(){

var clave=document.getElementById(‘clave’).value;

var valor=document.getElementById(‘texto’).value;

sessionStorage.setItem(clave,valor);

mostrar(clave);

}

function mostrar(clave){

var caj adatos=document.getElementById(‘caj adatos’);

var valor=sessionStorage.getItem(clave);

cajadatos.innerHTML='<div>’+clave+’ – ‘+valor+'</div>’;

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-3. Almacenando y leyendo datos.

El proceso es extremadamente simple. Los métodos son parte de sessionStorage y son llamados con la sintaxis sessionStorage.setItem(). En el código del Listado 10-3, la función nuevoitem () es ejecutada cada vez que el usuario hace clic en el botón del formulario. Esta función crea un ítem con la información insertada en los campos del formulario y luego llama a la función mostrar(). Esta última función lee el ítem de acuerdo a la clave recibida usando el método getItem() y muestra su valor en la pantalla.

Además de estos métodos, la API también ofrece una sintaxis abreviada para crear y leer ítems desde el espacio de almacenamiento. Podemos usar la clave del ítem como una propiedad y acceder a su valor de esta manera.

Este método usa en realidad dos tipos de sintaxis diferentes de acuerdo al tipo de información que estamos usando para crear el ítem. Podemos encerrar una variable representando la clave entre corchetes (por ejemplo, sessionStorage[clave] =valor) o podemos usar directamente el nombre de la propiedad (por ejemplo, sessionStorage.miitem=valor).

function iniciar(){

var boton=document.getElementById(‘grabar’);

boton.addEventListener(‘click’, nuevoitem, false);

}

function nuevoitem(){

var clave=document.getElementById(‘clave’).value;

var valor=document.getElementById(‘texto’).value;

sessionStorage[clave]=valor;

mostrar(clave);

}

function mostrar(clave){

var caj adatos=document.getElementById(‘caj adatos’);

var valor=sessionStorage[clave];

cajadatos.innerHTML='<div>’+clave+’ – ‘+valor+'</div>’;

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-4. Usando un atajo para trabajar con ítems.

Leyendo datos

El anterior ejemplo solo lee el último ítem grabado. Vamos a mejorar este código aprovechando más métodos y propiedades provistos por la API con el propósito de manipular ítems:

length Esta propiedad retorna el número de ítems guardados por esta aplicación en el espacio de almacenamiento. Trabaja exactamente como la propiedad length usada normalmente en Javascript para procesar arrays, y es útil para lecturas secuenciales. key(índice) Los ítems son almacenados secuencialmente, enumerados con un índice automático que comienzo por 0. Con este método podemos leer un ítem específico o crear un bucle para obtener toda la información almacenada.

function iniciar(){

var boton=document.getElementById(‘grabar’);

boton.addEventListener(‘click’, nuevoitem, false); mostrar();

}

function nuevoitem(){

var clave=document.getElementById(‘clave’).value; var valor=document.getElementById(‘texto’).value;

sessionStorage.setItem(clave,valor); mostrar();

document.getElementById(‘clave’).value=»; document.getElementById(‘texto’).value=»;

}

function mostrar(){

var caj adatos=document.getElementById(‘caj adatos’); caj adatos.innerHTML=’ ‘;

for(var f=0;f<sessionStorage.length;f++){ var clave=sessionStorage.key(f); var valor=sessionStorage.getItem(clave);

caj adatos.innerHTML+='<div>’+clave+’ – ‘+valor+'</div>’;

}

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-5. Lstando ítems.

El propósito del código en el Listado 10-5 es mostrar un listado completo de los ítems en la caja derecha de la pantalla. La función mostrar() fue mejorada usando la propiedad length y el método key (). Creamos un bucle for que va desde 0 al número de ítems que existen en el espacio de almacenamiento. Dentro del bucle, el método key() retornará la clave que nosotros definimos para cada ítem. Por ejemplo, si el ítem en la posición 0 del espacio de almacenamiento fue creado con la clave «miitem», el código sessionStorage.key(0) retornará el valor «miitem». Llamando a este método desde un bucle podemos listar todos los ítems en la pantalla con sus correspondientes claves y valores.

La función mostrar () es llamada desde la función iniciar() tan pronto como la aplicación es ejecutada. De este modo podremos ver desde el comienzo los ítems que fueron grabados previamente en el espacio de almacenamiento.

Hágalo usted mismo: Aproveche los conceptos estudiados con la API Forms en el Capítulo 6 para controlar la validez de los campos del formulario y no permitir la inserción de ítems vacíos o inválidos.

Eliminando datos

Los ítems pueden ser creados, leídos y, por supuesto, eliminados. Es hora de ver cómo eliminar un ítem. La API ofrece dos métodos para este propósito:

removeltem(clave) Este método eliminará un ítem individual. La clave para identificar el
ítem es la misma declarada cuando el ítem fue creado con el método setitem().
clear() Este método vaciará el espacio de almacenamiento. Todos los ítems serán eliminados.

function iniciar(){

var boton=document.getElementByld(‘grabar’);

boton.addEventListener(‘click’, nuevoitem, false); mostrar ();

}

function nuevoitem(){

var clave=document.getElementById(‘clave’).value;

var valor=document.getElementById(‘texto’).value;

sessionStorage.setItem(clave,valor); mostrar();

document.getElementById(‘clave’).value=»;

document.getElementById(‘texto’).value=»;

}

function mostrar(){

var caj adatos=document.getElementById(‘caj adatos’);

caj adatos.innerHTML='<div><button

onclick=»eliminarTodo()»>Eliminar Todo</button></div>’;

for(var f=0;f<sessionStorage.length;f++){ var clave=sessionStorage.key(f) ;

var valor=sessionStorage.getItem(clave);

cajadatos.innerHTML+='<div>’+clave+’ – ‘+valor+'<br><button onclick=»eliminar(\»+clave+’\’)»>Eliminar</button></div>’;

}

}

function eliminar(clave){

if(confirm(‘Está Seguro?’)){

sessionStorage.removeItem(clave); mostrar();

}

}

function eliminarTodo() {

if(confirm(‘Está Seguro?’)){ sessionStorage.clear();

mostrar();

}

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-6. Eliminando ítems.

Las funciones iniciar() y nuevoitem() en el Listado 10-6 son las mismas de códigos previos. Solo la función mostrar() cambia para incorporar el manejador de eventos onclick y llamar a las funciones que eliminarán un ítem individual o vaciarán el espacio de almacenamiento. La lista de ítems presentada en pantalla es construida de la misma manera que antes, pero esta vez un botón «Eliminar» es agregado junto a cada ítem para poder eliminarlo. Un botón para eliminar todos los ítems juntos también fue agregado en la parte superior.

Las funciones eliminar() y eliminarTodo() se encargan de eliminar el ítem seleccionado o limpiar el espacio de almacenamiento, respectivamente. Cada función llama a la función mostrar () al final para actualizar la lista de ítems en pantalla.

Hágalo usted mismo: Con el código del Listado 10-6, podrá estudiar cómo la información es procesada por sessionStorage. Abra la plantilla del Listado 10-1 en su navegador, cree nuevos ítems y luego abra la plantilla en una nueva ventana. La información en cada ventana es diferente. La vieja ventana mantendrá su información disponible y el espacio de almacenamiento de la nueva ventana estará vacío. A diferencia de otros sistemas (como Cookies de sesiones), para sessionStorage cada ventana es considerada una instancia diferente de la aplicación y la información de la sesión no se propaga entre ellas.

El sistema sessionStorage preserva los datos creados en una ventana solo hasta que esa ventana es cerrada. Es útil para controlar carros de compra o cualquier otra aplicación que requiere acceso a datos por períodos cortos de tiempo.

10.3   La localStorage

Disponer de un sistema confiable para almacenar datos durante la sesión de una ventana puede ser extremadamente útil en algunas circunstancias, pero cuando intentamos simular poderosas aplicaciones de escritorio en la web, un sistema de almacenamiento temporario no es suficiente.

Para cubrir este aspecto, Storage API ofrece un segundo sistema que reservará un espacio de almacenamiento para cada aplicación (cada origen) y mantendrá la información disponible permanentemente. Con localStorage, finalmente podemos grabar largas cantidades de datos y dejar que el usuario decida si la información es útil y debe ser conservada o no.

El sistema usa la misma interface que sessionStorage, debido a esto cada método y propiedad estudiado hasta el momento en este capítulo son también disponibles para localStorage. Solo la substitución del prefijo session por local es requerida para preparar los códigos.

function iniciar(){

var boton=document.getElementByld(‘grabar’);

boton.addEventListener(‘click’, nuevoitem, false);

mostrar();

}

function nuevoitem(){

var clave=document.getElementByld(‘clave’).value;

var valor=document.getElementById(‘texto’).value;

localStorage.setItem(clave,valor); mostrar();

document.getElementById(‘clave’).value=»;

document.getElementById(‘texto’).value=»;

}

function mostrar(){

var caj adatos=document.getElementById(‘caj adatos’);

caj adatos.innerHTML=’ ‘;

for(var f=0;f<localStorage.length;f++){ var clave=localStorage.key(f);

var valor=localStorage.getItem(clave);

caj adatos.innerHTML+='<div>’+clave+’ – ‘+valor+'</div>’;

}

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-7. Usando localStorage.

En el Listado 10-7, simplemente reemplazamos sessionStorage por localStorage en el código de uno de los ejemplos anteriores. Ahora, cada ítem creado será preservado a través de diferentes ventanas e incluso luego de que todas las ventanas del navegador son cerradas.

Hágalo usted mismo: Usando la plantilla del Listado 10-1, pruebe el código del Listado 10-7. Este código creará un nuevo ítem con la información insertada en el formulario y automáticamente listará todos los ítems disponibles en el espacio de almacenamiento reservado para esta aplicación. Cierre el navegador y abra el archivo HTML nuevamente. La información es preservada, por lo que podrá ver aún en pantalla todos los ítems ingresados previamente.

Evento storage

Debido a que localStorage hace que la información esté disponible en cada ventana donde la aplicación fue cargada, surgen al menos dos problemas: debemos resolver cómo estas ventanas se comunicarán entre sí y cómo haremos para mantener la información actualizada en cada una de ellas. En respuesta a ambos problemas, la especificación incluye el evento storage.

storage Este evento será disparado por la ventana cada vez que un cambio ocurra en el espacio de almacenamiento. Puede ser usado para informar a cada ventana abierta con la misma aplicación que los datos han cambiado en el espacio de almacenamiento y que se debe hacer algo al respecto.

function iniciar(){

var boton=document.getElementByld(‘grabar’); boton.addEventListener(‘click’, nuevoitem, false); window.addEventListener(«storage», mostrar, false);

mostrar();

}

function nuevoitem(){

var clave=document.getElementById(‘clave’).value; var valor=document.getElementById(‘texto’).value;

localStorage.setItem(clave,valor); mostrar();

document.getElementById(‘clave’).value=»; document.getElementById(‘texto’).value=»;

}

function mostrar(){

var caj adatos=document.getElementById(‘caj adatos’); caj adatos.innerHTML=’ ‘;

for(var f=0;f<localStorage.length;f++){ var clave=localStorage.key(f); var valor=localStorage.getItem(clave);

cajadatos.innerHTML+='<div>’+clave+’ – ‘+valor+'</div>’;

}

}

window.addEventListener(‘load’, iniciar, false);

Listado 10-8. Escuchando al evento storage para mantener la lista de ítems actualizada.

Solo necesitamos comenzar a escuchar al evento storage en la función iniciar() del código 10-8 para ejecutar la función mostrar () en cada ventana siempre que un ítem es creado, modificado o eliminado. Ahora, si algo cambia en una ventana, el cambio será mostrado automáticamente en el resto de las ventanas que están ejecutando la misma aplicación.

Espacio de almacenamiento

La información almacenada por localStorage será permanente a menos que el usuario decida que ya no la necesita. Esto significa que el espacio físico en el disco duro ocupado por esta información probablemente crecerá cada vez que la aplicación sea usada. Hasta este momento, la especificación de HTML5 recomienda a los fabricantes de navegadores que reserven un mínimo de 5 megabytes para cada origen (cada sitio web o aplicación).

Esta es solo una recomendación que probablemente cambiará dramáticamente en los próximos años. Algunos navegadores están consultando al usuario si expandir o no el espacio disponible cuando la aplicación lo necesita, pero usted debería ser consciente de esta limitación y tenerla en cuenta a la hora de desarrollar sus aplicaciones.

IMPORTANTE: Muchos navegadores solo trabajan de forma adecuada con esta API cuando la fuente es un servidor real. Para probar los siguientes códigos, le recomendamos que primero suba los archivos a su servidor.

10.4    Referencia rápida

Con la ayuda de la API Web Storage, ahora las aplicaciones web pueden ofrecer un espacio de almacenamiento. Usando un par clave/valor, la información es almacenada en el ordenador del usuario para un rápido acceso o para trabajar desconectado de la red.

Tipo de almacenamiento

Dos mecanismos diferentes son ofrecidos para almacenar datos:

sessionStorage Este mecanismo mantiene la información almacenada solo disponible para una simple ventana y solo hasta que la ventana es cerrada. localStorage Este mecanismo almacena datos de forma permanente. Estos datos son compartidos por todas las ventanas que están ejecutando la misma aplicación y estarán disponibles a menos que el usuario decida que ya no los necesita.

Métodos

La API incluye una interface común para cada mecanismo que cuenta con nuevos métodos, propiedades y eventos:

setItem(clave, valor) Este método crea un nuevo ítem que es almacenado en el espacio de almacenamiento reservado para la aplicación. El ítem está compuesto por un par clave/valor creado a partir de los atributos clave y valor. getItem(clave) Este método lee el contenido de un ítem identificado por la clave especificada por el atributo clave. El valor de esta clave debe ser el mismo usado cuando el ítem fue creado con el método setitem(). key(índice) Este método retorna la clave del ítem encontrado en la posición especificada por el atributo índice dentro del espacio de almacenamiento. removeItem(clave) Este método elimina un ítem con la clave especificada por el atributo clave. El valor de esta clave debe ser el mismo usado cuando el ítem fue creado por el método setItem().

clear() – Este método elimina todos los ítems en el espacio de almacenamiento reservado para la aplicación.

Propiedades

length Esta propiedad retorna el número de ítems disponibles en el espacio de almacenamiento reservado para la aplicación.

Eventos

storage Este evento es disparado cada vez que un cambio se produce en el espacio de almacenamiento reservado para la aplicación.

Publicaciones Similares