Cookies 2.0 mit HTML5
Selbst für die Verhältnisse von Web-Technologie ist die konfuse Situation rund um Cookies eine Katastrophe. Erst drei Jahre nachdem sie von Netscape Anno 1994 erfunden wurden, wurde mit RFC 2109 die erste formale Cookie-Spezifikation veröffentlicht und in der Folgezeit von den Browserherstellern weitgehend ignoriert. Der Revision RFC 2965 erging es nicht viel besser und angesichts dessen, was dort geschrieben steht, ist es vielleicht auch ganz gut so. Cookies sind heutzutage das Mittel der Wahl, um im Browser Daten zu speichern, obwohl sie dazu denkbar ungeeignet sind [1] – nicht nur sind die Spezifikationen an sich unbrauchbar, auch die Speicherkapazität ist extrem beschränkt, während Cookies gleichzeitig jeden HTTP-Request unnötig aufblähen.
Sieht man von allen Sicherheits- und Spezifikationsfragen ab, ist dem von HTML5 verwöhnten Webentwickler vor allem die fehlende Leistungsfähigkeit von Cookies ein Dorn im Auge. Was die moderne Webapp braucht, ist eine einfache API für einen zuverlässigen Speichermechanismus, der mehr als ein paar Bytes an Kapazität aufbieten kann. Web-Storage ist genau so eine API.
Web-Storage mit HTML 5
Web-Storage spezifiziert eine JavaScript-Schnittstelle für einen clientseitigen Datenspeichermechanismus im Browser [2]. Es ist weniger mit einem vollwertigen Datenbanksystem im Stile von MySQL als vielmehr mit Cookies zu vergleichen, wenn auch wesentlich leistungsfähiger als letztgenannte. Neben den üblichen Cookie-Aufgaben, wie etwa der Speicherung von Logindaten, kann Web-Storage auch als Mini-Datenbank für Webapps dienen, vorausgesetzt man überfordert das bewusst einfach gehaltene Key-Value-Interface nicht mit Unmengen komplexer Datensätze. Die Browserunterstützung fällt recht umfassend aus:
- Firefox: ab Version 3.5
- Opera: ab 10.63
- Safari (inkl. iOS): ab 3.1
- Chrome: ab 5.0
- Android: ab 2.2
- Internet Explorer: ab 8
Diese Browser bringen eine umfassende Unterstützung mit – teilweise haben aber auch ältere Browserversionen schon Teile von Web-Storage implementiert. Eine Übersicht über alle Browserversionen findet sich im Web [3]. Die API von Web-Storage ist ausgesprochen simpel: Mit der Funktion „setItem()“ speichert man einen Datensatz, mit „getItem()“ liest man ihn wieder aus und „removeItem()“ löscht:
// Wir speichern einen Datensatz ... localStorage.setItem('key', 'foo'); // ... lesen ihn wieder aus ... localStorage.getItem('key'); // ... und löschen ihn schließlich localStorage.removeItem('key');
Listing 1
In diesem Beispiel werden die Speicher-Funktionen auf dem globalen JavaScript-Objekt „localStorage“ ausgeführt, das eine von zwei so genannten Storage-Areas repräsentiert.
Storage-Areas
Es gibt mit „localStorage“ und „sessionStorage“ zwei Storage-Area genannte Speicherbereiche, in die man Daten ablegen kann. Im Browser repräsentieren die globalen Objekte „localStorage“ und „sessionStorage“, die beide das exakt gleiche Set an Methoden und DOM-Attributen implementieren, diese beiden Bereiche. Der Unterschied zwischen beiden Bereichen liegt in der Lebensdauer der Daten: Während in „localStorage“ gespeicherte Daten theoretisch unbegrenzt lange halten, verfallen die Datensätze in „sessionStorage“ mit dem Ende der Sitzung, also nach einen Neustart oder Absturz des Browsers.
Egal in welcher Storage-Area man seine Daten ablegt: Einmal gespeicherte Informationen kann nur die Webanwendung auslesen und bearbeiten, die diese Daten auch gespeichert hat, denn Web-Storage unterliegt der Same-Origin-Policy. Die Daten sind nach der Kombination von Host, Protokoll und Port getrennt; was die Webseite www.foo.com abspeichert, kann www.bar.de nicht auslesen. Vorsicht: Diese Trennung bedeutet auch, dass http://www.foo.com und https://www.foo.com als zwei getrennte Webseiten behandelt werden.
Web-Storage ist naturgemäß ein lohnenswertes Ziel für Datendiebe. Der Same-Origin-Mechanismus sorgt zwar für eine gewisse Grundsicherheit. Gegen Laptopdiebstahl, Cross-Site-Scripting und andere fortschrittlichere Attacken hilft das aber natürlich nicht, so dass man sich im Sinne der Datensicherheit wirklich gut überlegen sollte, was man clientseitig abspeichern möchte und was nicht. Durch die Einführung von Offline-Speicher macht HTML5 das Web nicht, wie manch einer behauptet, per se unsicherer [4], doch die mögliche Ausbeute für kriminelle Aktivitäten wird wesentlich attraktiver.
Das Storage-Interface
Egal ob die Daten nur eine Sitzung oder bis in alle Ewigkeit halten sollen, die Programmierung gestaltet sich in beiden Fällen identisch. Sowohl „localStorage¡“ als auch „sessionStorage“ (beide in Browsern als globale Objekte implementiert) bieten die exakt gleichen Funktionen.
- setItem(‚key‘, ‚foo‘) speichert den String ‚foo‘ unter dem Schlüssel ‚key‘. Der Schlüssel muss immer als String angegeben werden, speichern kann man alle gültigen JavaScript-Datentypen
- getItem(‚key‘) liest die unter dem Schlüssel ‚key‘ gespeicherten Daten aus und gibt sie zurück
- length gibt an, wie viele Datensätze in der Storage-Area vorhanden sind
- key(n) gibt den Schlüssel an der Position n zurück
- removeItem(‚key‘) löscht unter dem Schlüssel ‚key‘ gespeicherten Daten
- clear() löscht alle Daten aus der Storage Area
Beim Speichern oder Löschen von Daten soll ein spezielles Storage Event auf dem „document“-Objekt feuern. Allerdings soll dies nicht auf dem „document“-Objekt passieren, das die Speicherung oder die Löschung ausgelöst hat, sondern auf allen anderen, die außer dem aktuellen Dokument ebenfalls Zugriff auf die Daten haben, also zum Beispiel weitere Tabs im Browser, die das gleiche Dokument anzeigen. Der Gedanke dahinter ist, dass auf diese Weise mehrere Dokumente über die Grenzen von Browserfenstern oder Frames hinweg immer mitbekommen, wann sich etwas in Sachen Web-Storage tut. Zwar findet sich das Event an sich in fast allen Browsern, nur richtig implementiert ist es in den wenigsten. Die Spezifikationen sehen zum Beispiel vor, dass die Eventobjekte Aufschluss über eventuell überschriebene Altdaten geben, was man jedoch in fast keinem Browser in einer brauchbaren Form vorfindet.
Browser stellen ohnehin noch ein Problem dar, denn obwohl der Internet Explorer seit Version 8 native Unterstützung für Web-Storage bietet, sieht es bei seinen kreidezeitlichen Vorfahren vergleichsweise finster aus… möchte man meinen! Doch JavaScript-Hacker finden immer einen Weg.
Cross-Browser-Storage-Frameworks
Die Idee, den Browser Daten speichern zu lassen, kam Microsoft schon mit dem IE5. Leider ist die API, die man seitdem in allen Internet Explorern findet, genau so, wie man sich eine IE5-API aus Zeiten des Browserkrieges vorstellt: komisch und kompliziert. Wenn man es aber schafft, die IE5-API und das moderne Web-Storage unter einen Framework-Hut zu bringen, hat man auf einmal eine leistungsfähige Speichertechnik, die in allen heute relevanten Browsern funktioniert.
jStorage [5] ist ein Speicherframework, das unter seiner Web-Storage nachempfundenen API die verschiedensten Datenspeicher-Schnittstellen vereinigt. So kann man mit Hilfe einiger Methoden sicher und zuverlässig Daten ablegen und überlässt die Wahl der jeweils verwendeten Technologien und den Kampf gegen die API einem Skript.
// Wenn wir speichern können... if($.jStorage.storageAvailable()){ // ... speichern wir Daten... $.jStorage.set('key', 'foo'); // ... und lesen sie wieder aus $.jStorage.get('key'); }
Listing 2
Je nachdem welcher Browser die Webseite abruft verwendet dieser Code Web-Storage, die IE5-API, Cookies oder etwas ganz anderes zum Speichern. jStorage ist als Plugin für Mootools, Prototype oder jQuery zu haben.
Was tun bei komplexen Daten?
Web-Storage ist zwar leistungsfähiger als das Cookie-Chaos, aber nicht viel. Das ist auch durchaus so gedacht, denn HTML5 hält für richtige clientseitige Datenbanken noch andere Spezifikationen bereit – genannt seien Indexed Database [6] und die mittlerweile eingestellte Web SQL Database. Die Umsetzung dieser übrigen Technologien ist zurzeit noch so löchrig, dass an den Einsatz in allen Browsern nicht zu denken ist. Für den Moment ist Web-Storage die einzige HTML5-Offlinetechnologie, die wirklich überall funktioniert. Dem Produktiveinsatz steht nichts im Weg.
Hallo,
eine interessante Alternative stellt auch PublicSQL da. Damit können Tabellen in einem CSV-ähnlichen Format mit einfachen SQL-Befehlen in Javascript verarbeitet werden. Eine Speicherung der Daten auf dem Anwender-Rechner ist allerdings nicht möglich. Ansonsten bietet die Open Source Software aber viele Möglichkeiten. Die Open-Source Software ist unter http://www.publicsql.org zu finden. Auf der Website befindet sich auch ein einfacher Editor (Windows) zum Erstellen und Bearbeiten der Tabellen.