Features von übermorgen: Async Cookies API

Tales from the Web side  –  0 Kommentare

Die Schnittstelle, um in JavaScript mit Cookies zu arbeiten, hat mindestens zwei Probleme: Zum einen ist der Zugriff auf Cookies nicht gerade komfortabel, zum anderen ist die Synchronität der Operationen rund um document.cookie nicht mehr zeitgemäß. Dagegen will die Async Cookies API Abhilfe schaffen.

Einschränkungen der aktuellen Cookie API

Bislang ist das Arbeiten mit Cookies alles andere als komfortabel. So stehen für das Hinzufügen, das Auslesen und das Löschen von Cookies standardmäßig überhaupt keine Methoden zur Verfügung. All das muss "händisch" über die Eigenschaft document.cookie gemacht werden. Zum Beispiel das Hinzufügen:

document.cookie = 'examplecookie=hello; 
expires=Thu, 25 Oct 2016 20:00:00 UTC; path=/'

Hierbei wird der Eigenschaft document.cookie eine Zeichenkette zugewiesen, die das entsprechende Name-/Wert-Paar für den Cookie enthält, gefolgt von einem Semikolon und einem Whitespace, gefolgt von der Angabe des Datums, bis zu dem das Cookie gültig sein soll, erneut gefolgt von Semikolon und Whitespace und zu guter Letzt der Pfadangabe. Sehr fehleranfällig und nicht schön zu verwenden.

Zu beachten ist hierbei auch, dass es sich bei der Eigenschaft document.cookie selber um keine Zeichenkette handelt. Man weist der Eigenschaft zwar Zeichenketten zu, intern werden diese dann aber zu den bereits definierten Cookies hinzugefügt. Das zeigt sich, wenn man wie im folgenden Listing zwei Cookies nacheinander hinzufügt und anschließend jeweils die Cookies ausliest (was ebenfalls über die Eigenschaft document.cookie geschieht).

document.cookie = 'examplecookie=hello; 
expires=Thu, 25 Oct 2016 20:00:00 UTC; path=/'
document.cookie; // "examplecookie=hello"
document.cookie = 'examplecookie2=world;
expires=Thu, 25 Oct 2016 20:00:00 UTC; path=/'
document.cookie; // "examplecookie=hello; examplecookie2=world"

Ist das Hinzufügen von Cookies über die aktuelle Cookie API (wenn man sie denn überhaupt als solche bezeichnen möchte) schon nicht schön, ist der Zugriff auf die Werte einzelner Cookies oder das Löschen einzelner Cookies richtig hässlich: In diesen Fällen führt nämlich kein Weg daran vorbei, die von document.cookie zurückgegebene Zeichenkette zu parsen. Und das macht auch nicht mit regulären Ausdrücken wirklich Spaß. Bibliotheken wie js-cookie schaffen diesbezüglich zwar Abhilfe, indem sie die genannten Operationen über entsprechende Funktionen vereinfachen, lösen aber nicht das eigentliche Problem.

Schwerwiegender als das umständliche Parsen von Cookies dürfte nämlich die Tatsache sein, dass alle Operationen, die man über document.cookie anstößt, synchron ablaufen, nicht asynchron, was in Vergangenheit nicht selten bereits Grund für Performanceprobleme war.

Ebenfalls problematisch wird es, wenn man innerhalb eines Service Workers auf Cookies zugreifen möchte. Das ist nämlich Stand heute überhaupt erst gar nicht möglich, und zwar aus dem Grund, da Service Worker keinen Zugriff auf das DOM haben, die Eigenschaft cookie aber genau an document, dem Einstiegspunkt des DOM, definiert ist.

Die Async Cookies API

Lange Rede, kurzer Sinn: Langfristig sollte aus den genannten Gründen eine Alternative her, die bereits standardmäßig von Browsern unterstützt wird. Und genau an solch einer Alternative arbeitet gerade die Web Incubator Community Group und hat mit der Async Cookies API bereits einen ersten Vorschlag entworfen.

Die Idee dabei ist, zum einen Cookies nicht mehr (nur) über die Eigenschaft document.cookies zu verwalten, sondern über ein neues Objekt namens cookieStore, welches sowohl innerhalb einer Webseite als auch innerhalb von Service Workern zur Verfügung stünde.

Der Vorschlag sieht dabei die Methoden write() bzw. set() für das Hinzufügen von Cookies, delete() für das Löschen und read() für das Lesen von Cookies vor, wobei alle Methoden asynchron ablaufen und jeweils Promise-Objekte zurückgeben. Ein Code-Beispiel für das Hinzufügen eines Cookies könnte also wie folgt aussehen:

cookieStore.set(
'examplecookie3',
'helloworld',
{
expires: Date.now() + 24*60*60*1000,
domain: 'heise.de'
})
.then(() => {
console.log('Cookie gesetzt');
})
.catch(error => {
console.error(
'Cookie konnte nicht gesetzt werden:',
error
);
});

Sauber, schön, intuitiv zu verwenden. So stellt man sich als Entwickler eine moderne API vor.

Neben diesen Standardoperationen soll es über die Interfaces CookieObserver und CookieChangeEvent zudem möglich sein, über Änderungen an Cookies informiert zu werden:

// Verwenden von CookieObserver
let callback = (cookieChanges, observer) => {
cookieChanges.forEach(({cookieStore, type, url, name, value}) => {
/* ... */
}
}
let observer = new CookieObserver(callback);
observer.observe(cookieStore);

// Verwenden von CookieChangeEvent
addEventListener('cookiechange', event => {
let cookieChanges = event.detail;
cookieChanges.forEach(({cookieStore, type, url, name, value}) => {
/* ... */
});
});
Fazit und Ausblick

Ziel der Async Cookies API ist es, eine asynchrone API für das Arbeiten mit Cookies bereitzustellen. Der Vorschlag ist noch relativ jung (der erste Commit in GitHub ist Stand heute 8 Monate alt) und wird daher auch noch von keinem aktuellen Browser unterstützt. Wer die API aber schon heute in Aktion sehen bzw. selber testen möchte, kann sich bereits ein entsprechendes Polyfill herunterladen. Der Diskussion folgen und Feedback geben kann man unter GitHub oder unter diesem Link.