Achtung! Die im folgenden beschriebene Technik des AppCaches ist nicht mehr Zeitgemäß. Sie wurde abgekündigt und durch ServiceWorker ersetzt. Da Sie in diesem Projekt zu unschönen Fehlern führt habe ich den AppCache auch hier ausgemustert.
Da der Browser Dateien nur recht unzuverlässig in seinem normalen Cache vorhält, ist es schwierig das Programm, also die HTML-, CSS- und Javascriptdateien, auch dann auszuführen wenn der Computer offline ist. Um dieses Problem zu beseitigen gehört zu HTML5 der sogenannte Application Cache. Diesen Cache kann ich als Webentwickler relative gut steuern und erhalte die nötige Zuverlässigkeit da es keine Automatismen zum Aufräumen gibt die Inhalte vorzeitig löschen.
Manifest
Was im Application Cache landet wird durch die Manifest-Datei festgelegt. In dieser Datei steht welche URL’s in den Cache aufgenommen werden sollen und welche immer direkt aus dem Netz geladen werden sollen. Für alles URL’s die nicht in eine der beiden obigen Kategorien fallen kann man zusätzlich noch eine Fallback-Datei angeben. Diese wird immer angezeigt wenn eine Datei verwendet wird die nicht im Cache vorliegt.
Ein beispielhaftes Manifest könnte so aussehen:
CACHE MANIFEST
# Version 2014-01-01 12:36
CACHE:
./ApplicationCache.html
./ApplicationCache.js
../css/main.css
NETWORK:
*
In diesem Beispiel werden die drei Dateien ApplicationCache.html, ApplicationCache.js und main.css in den Cache aufgenommen. Alle anderen Scripte und Stylesheets sollen aus dem Internet geladen werden. Das bewirkt der Platzhaltern *
in der NETWORK-Sektion. Wenn man diese Angabe weglässt stolpert man über einen 404-HTTP-Fehler nach dem anderen. Alle nicht explizit in der Manifest-Datei aufgeführten URL’s werden nämlich grundsätzlich nicht geladen, selbst wenn man gerade eine Internetverbindung hat.
Die Manifest-Datei funktioniert übrigens nur wenn sie vom Webserver mit dem richtigen Mime-Type ausgeliefert wird. Der Type muss text/cache-manifest lauten. Ich habe daher den entsprechenden Verweis AddType text/cache-manifest manifest
in die Datei .htaccess meines Webspaces integriert.
Wenn man erst einmal eine Manifest-Datei erstellt hat stellt sich als nächstes die Frage wie man diese Veröffentlicht. Dazu gibt es das neue Attribut manifest
das man im HTML
-Element angeben kann:
<html manifest="ApplicationCache.manifest">
…
</html>
Das Attribut bewirkt zweierlei. Einerseits wird die Datei die es enthält in den Application Cache aufgenommen und andererseits wird das im Wert angegebene Manifest wie oben beschrieben angewendet.
API & Events
Jedesmal wenn, bei bestehender Internetverbindung, eine Webseite aufgerufen wird die ein manifest-Attribute enthält wir das entsprechende Manifest geladen und überprüft ob es seit dem letzten mal verändert wurde. Bei diesem Vorgang werden einige Events ausgelöst. Dieses Events bilden auch schon fast die gesamte API des Application Caches. Im einzelnen sind dies checking
, noupdate
, downloading
, progress
, cached
, updateready
, obsolete
und error
.
Außer den Events gibt es nur noch drei Methoden (update()
, abort()
und swapCache()
) und eine Status-Variable status
. Die Methoden sind selbsterklärend, nur swapCache() bedarf einiger kurzer Worte. Es existieren nach einem Update des Caches quasi zwei davon. Derjenige der aktuell war als die Seite aufgerufen wurde und der nach dem Update. swapCache() schaltet auf den neuesten Cache um, dies geschieht sonst nämlich nur bei einem Reload der HTML-Seite.
Probleme und Stolpersteine
Mein Hauptkritikpunkt am Application Cache betrifft dessen Update-Policy. Der Inhalt des Caches wird nämlich nur dann aktualisiert wenn das Manifest geändert wird. Es spielt leider keine Rolle ob die Dateien die im Cache gespeichert sind auf dem Server geändert wurden oder nicht, lediglich das Änderungsdatum und die Größe der Manifest-Datei sind ausschlaggebend. Das zwingt mich als Entwickler dazu eine Versions-Nummer oder etwas vergleichbares im Manifest unterzubringen und diese Nummer jedes mal anzupassen wenn es Änderungen an meiner Applikation gibt.
Ausblick
Um die Events des Application Cache zu beobachten habe ich eine kleine Testseite bereitgestellt die die aufgetretenen Events anzeigt. Die Manifest-Datei wird dabei dynamisch mit Python generiert und ändert so ihren Inhalt einmal in der Minute. Um also ein Update des Cache zu beobachten muss man die Seite lediglich nach einer Minute neu laden.
Zusammen mit dem File System API und dem Web Storage API habe ich jetzt alle Möglichkeiten unter Chromium-Basierten Browsern die Offlinefähigkeit meines Podcatchers zu realisieren. Damit steht einem ausführlichen Test nichts mehr im Wege.