Sin Conexión HTML5
Sin Conexión HTML5
Algunas de las ventajas que conlleva el uso de ésta caché para una aplicación son:
• Navegación sin conexión: los usuarios pueden explorar todo el sitio web sin conexión.
• Velocidad: los recursos almacenados en caché son locales y, por tanto, se cargan más
rápido.
• Reducción de carga del servidor: el navegador solo descarga recursos del servidor que
han cambiado.
Para poder trabajar sin conexión, una aplicación únicamente necesita de un archivo de
manifiesto, el cual indica al navegador que ficheros debe almacenar en la caché local. El
contenido del manifiesto puede ser tan simple como un listado de archivos. Una vez que el
navegador ha descargado y almacenado los ficheros (html, CSS, imágenes, javascripts, etc), el
navegador hace uso de estos ficheros, incluso cuando el usuario actualiza la página en su
navegador.
Además de especificar qué ficheros van a ser almacenados en la caché, es posible indicar
cuáles no tienen que serlo, y por tanto obligar al navegador a realizar una petición de dichos
ficheros al servidor. Finalmente, si intentamos acceder a un fichero no almacenado en local, y
no disponemos de conexión, podemos mostrar un recurso que previamente hemos
almacenado en la caché.
<!DOCTYPE html>
<html lang="en" manifest="/example.appcache">
...
</html>
El atributo manifest debe estar incluido en todas las páginas de nuestra aplicación, que
queramos que se almacenen en la caché. Es decir, además de los ficheros indicados en el
manifiesto, la propia página que incluye el manifiesto es almacenada en la caché. El navegador
no almacenará en caché ninguna página que no contenga el atributo manifest (a menos que
esa página aparezca explícitamente en el propio archivo de manifiesto).
El atributo manifest puede señalar a una URL absoluta o a una ruta relativa, pero las URL
absolutas deben tener el mismo origen que la aplicación web. Un archivo de manifiesto puede
tener cualquier extensión, pero se debe mostrar con el tipo MIME correcto:
<html manifest="http://www.example.com/example.mf">
...
</html>
El tipo MIME con el que se deben mostrar los archivos de manifiesto es text/cache-
manifest . Es posible que se tenga que añadir un tipo de archivo personalizado a la
configuración de .htaccess o de tu servidor web.
9.1.1 ESTRUCTURA
Ejemplo de un archivo de manifiesto sencillo:
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
El archivo de manifiesto del ejemplo permite almacenar en caché los cuatro archivos
especificados. El formato del manifiesto es importante:
• Dentro del manifiesto, los ficheros son listados dentro de categorías, también conocidos
como namespaces . Si no se especifica ninguna categoría, todos los ficheros pertenecen
a la categoría CACHE .
CACHE MANIFEST
# 2010-06-18:v2
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
# Resources that require the user to be online.
NETWORK:
login.php
/myapi
http://api.twitter.com
• CACHE : esta es la sección predeterminada para las entradas. Los archivos incluidos en
esta sección (o inmediatamente después de CACHE MANIFEST ) se almacenarán en caché
explícitamente después de descargarse por primera vez.
• NETWORK : los archivos incluidos en esta sección son recursos permitidos que requieren
conexión al servidor. En todas las solicitudes enviadas a estos recursos se omite la
caché, incluso si el usuario está trabajando sin conexión. Se pueden utilizar caracteres
comodín.
• FALLBACK : se trata de una sección opcional en la que se especifican páginas alternativas
en caso de no poder acceder a un recurso. La primera URI corresponde al recurso y la
segunda, a la página alternativa. Ambas URI deben estar relacionadas y tener el mismo
origen que el archivo de manifiesto. Se pueden utilizar caracteres comodín.
CACHE MANIFEST
# 2010-06-18:v3
Nota
Las peticiones de recursos que den como resultado un error 404 (por ejemplo una
imagen no encontrada), mostrarán en este caso el fichero offline.html
text/cache-manifest appcache
Esta configuración dependerá del servidor web que utilicemos. De todas maneras, para
asegurarnos que el servidor está enviando el manifiesto con la cabecera correcta, podemos
utilizar una herramienta como curl de la siguiente manera:
curl -I http://mysite.com/manifest.appcache
HTTP/1.1 200 OK
Date: Mon, 13 Sep 2010 12:59:30 GMT
Server: Apache/2.2.13 (Unix) mod_ssl/2.2.13 OpenSSL/0.9.8l DAV/2 PHP/5.
3.0
Last-Modified: Tue, 31 Aug 2010 03:11:00 GMT
Accept-Ranges: bytes
Content-Length: 113
Content-Type: text/cache-manifest
Ahora, el navegador está listo y la caché contiene los ficheros indicados en el manifiesto. Si el
manifiesto no ha cambiado, y la página se recarga, ocurre lo siguiente:
Una vez que el navegador tiene almacenados los recursos en su caché, los sirve de manera
local y después solicita el manifiesto. Como se puede ver en la siguiente captura de pantalla,
Google Chrome únicamente solicita al servidor aquellos ficheros que no se encuentran en la
caché de la aplicación.
Figura 9.1 Peticiones realizadas por Google Chrome
# 2010-06-18:v3
2. Navegador: detecta que tiene una copia local de index.html y la sirve de manera local.
3. Navegador: procesa la página index.html y los recursos existentes en la caché se sirven
de manera local.
Hay que destacar, que a pesar de haber modificado los recursos en el navegador, estos
cambios no se producen en este momento, ya que se siguen utilizando los cargados
previamente. La nueva caché solo estaría disponible si volviésemos a recargar la página. Una
manera de modificar este comportamiento es accediendo al objeto applicationCache .
Para actualizar la caché mediante JavaScript, primero se debe hacer una llamada a
applicationCache.update() . Al hacer esa llamada, se intentará actualizar la caché del
usuario (para lo cual será necesario que haya cambiado el archivo de manifiesto). Finalmente,
cuando el estado de applicationCache.status sea UPDATEREADY , al llamar a
applicationCache.swapCache() , se sustituirá la antigua caché por la nueva.
if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache(); // The fetch was successful, swap in the new
cache.
}
Para que los usuarios puedan acceder a la versión más reciente del contenido de tu sitio,
podemos establecer un escuchador que controle el evento updateready cuando se cargue la
página:
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e)
{
if (window.applicationCache.status == window.applicationCache.UP
DATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load i
t?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
Hay, además, algunos eventos adicionales que permiten controlar el estado de la caché. El
navegador activa eventos para una serie de acciones (como el progreso de las descargas, la
actualización de la caché de las aplicaciones y los estados de error). El siguiente fragmento
permite establecer escuchadores de eventos para cada tipo de evento de caché:
function handleCacheEvent(e) {}
function handleCacheError(e) {
alert('Error: Cache failed to update!');
};
// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);
Una manera de identificar si existe conexión a internet, es utilizar la categoría FALLBACK del
manifiesto. En esta categoría podemos indicar dos ficheros JavaScript que detectan si estamos
online o no:
CACHE MANIFEST
FALLBACK:
online.js offline.js
online.js contiene:
setOnline(true);
Y offline.js contiene:
setOnline(false);
En nuestra aplicación, creamos una función llamada testOnline que dinámicamente crea un
elemento <script> , el cual trata de cargar el fichero online.js . Si la carga se realiza de
manera correcta, se ejecuta el método setOnline(true) . Si estamos offline, el navegador
cargará el fichero offline.js , ejecutando el método setOnline(false) .
function testOnline(fn) {
var script = document.createElement(‘script’)
script.src = 'online.js';
// alias the setOnline function to the new function that was passed
in
window.setOnline = function (online) {
document.body.removeChild(script);
fn(online);
};
testOnline(function (online) {
if (online) {
applicationCache.update();
} else {
// show users an unobtrusive message that they're disconnected
}
});
Ejercicio 11
Ver enunciado
ÍNDICE DE CONTENIDOS
Sin conexión