Cache Manifest dynamisch erstellen

Cache Manifest dynamisch erstellen

Von am 06.04.2012

Will man eine Webanwendung auch ohne Netzwerkverbindung verfügbar machen, müssen im ersten Schritt alle serverseitigen Programmiersprachen verbannt werden. Im Klartext heißt das bei mir, PHP kommt nur noch für einen kleinen Webservice zum Einsatz, der via AJAX-Calls angesprochen wird. Alle anderen Dateien sind HTML-, JavaScript-, CSS- oder Bilddateien.

Im zweiten Schritt kommt das Cache Manifest ins Spiel, dass im aktuellen Working Draft zu HTML5 spezifiziert ist. Die Datei enthält Informationen, welche Ressourcen meine Website benötigt. Werden für die eigene Webseite nicht viele Dateien benötigt, kann man die Datei händisch erstellen. Diese sieht dann wie folgt:

CACHE MANIFEST
./js/mobilot.js
./css/mobilot.css
./image/icon_sprite.png
./image/icon_sprite@2x.png

Wichtig ist, dass sie mit CACHE MANIFEST beginnt. Anschließend werden alle notwendigen Dateien jeweils in einer Zeile aufgelistet. In meinem Fall habe ich sie als relative Pfade definiert, es können aber auch absolute Pfade angegeben werden. Wird die Website komplexer, bietet es sich an, die Erstellung der Cache Manifest Datei über ein Skript zu lösen. Ich habe das so realisiert:

<?php
header('Content-Type: text/cache-manifest');
echo "CACHE MANIFEST\n";
$hashes = '';

$dir = new RecursiveDirectoryIterator(".");
foreach(new RecursiveIteratorIterator($dir) as $file){
if($file->IsFile()&& !strpos($file, "/.") && substr($file->getFilename(), 0, 1) !="." && substr($file->getFilename(), -3, 3) != "php"){
echo $file . "\n";
$hashes .= md5_file($file);
}
}
echo "# HASH: ".md5($hashes) . "\n";
?>

Das Skript (inspiriert durch [1] und [2]) iteriert durch alle Unterverzeichnisse und schließt sowohl Dateien aus, die mit “.” beginnen als auch alle PHP-Dateien. Zusätzlich wird ein md5-Hash der Files generiert und dieser am Ende der Manifest-Datei als Kommentar ausgegeben. So kann sichergestellt werden, dass bei Änderung eines Files das Cache Manifest geändert wird und somit der Browser die Ressourcen neu lädt.

Die Manifest Datei muss mit dem Content-Type “text/cache-manifest” vom Server ausgeliefert werden. Wird sie manuell erstellt, kann dies bei einem Apache Webserver über die .htaccess-Datei erreicht werden. In diesem Fall muss dort die Zeile AddType text/cache-manifest .manifest hinzugefügt werden. In meinem PHP-Script erledigt das die Zeile header('Content-Type: text/cache-manifest'); für mich.

Außerdem kann im Manifest spezifiziert werden, welche Dateien nicht gespeichert werden sollen und somit egal ob offline oder nicht immer vom Server geladen werden. Dies wird über den Bereich NETWORK: erreicht und nennt sich Whitelisting. Wichtig ist zu wissen, dass nur Dateien, die nicht zum Cachen angeführt sind, in diesem Bereich angeführt werden können. Zudem kann ein Bereich FALLBACK: definiert werden, in dem zwischen Online- und Offline-Verfügbarkeit unterschieden werden kann. Eine einfache Manifest-Datei könnte dann wie folgt aussehen:

CACHE MANIFEST
./js/mobilot.js
./css/mobilot.css
./image/icon_sprite.png
./image/icon_sprite@2x.png

NETWORK:
./image/menu.png

FALLBACK:
./image/ ./offline.png

In diesem File wird die im Ordner image liegende menu.png immer vom Server geladen (definiert im Bereich NETWORK:). Aus dem Bereich FALLBACK: können wir entnehmen: wenn eine Verbindung zum Netzwerk besteht, dann lade die Dateien im Ordner image, sonst lade die Datei offline.png.

Und zu guter Letzt muss der Startdatei der Webseite (in dem meisten Fällen wohl die index.html) im HTML Tag die Cache Manifest Datei verlinkt werden. Dazu wird das Attribut manifest gesetzt.
<html manifest="cache.manifest"> oder auch z.B. <html manifest="manifest.php">

Update 06.04.2012: Als Tücke beim Arbeiten mit dem Cache Manifest hat sich für mich heute herausgestellt, dass nur Dateien offline aufgerufen werden können, deren URL genau gleich im Cache Manifest hinterlegt sind. Das bedeutet, dass keine zusätzlichen Parameter beim Aufruf mitgegeben werden können, die nicht auch im Cache Manifest hinterlegt sind.


[1] Stark, J. (2011). Android-Apps mit HTML, CSS und JavaScript [mit Standard-Web-Tools zur nativen App]. Beijing; Cambridge; Farnham; Köln; Sebastopol; Tokyo: O’Reilly.
[2] Kessin, Z. (2011). Programming web applications in HTML5. Sebastopol CA: O’Reilly Media, Inc.

1 Kommentar

  • Grischa am 14.05.2012 um 12:46

    Anm. zum Update 06.04.2012:

    Wenn man den Parameter nicht per ? (= GET-Param) sondern per # (= Anchor innerhalb der Seite) getrennt mitgibt, klappt es aber, oder?

    Dass der Anchor (also ein < a name…. gar nicht existiert, müsste ja egal sein, per Javascript sollte trotzdem die aufgerufene URL ausgelesen werden können.

The comments are closed.