Javascript Cookies

Javascript Cookies sehen aus wie ein String

Javascript erzeugt, liest und löscht Cookies mit document.cookies. Wir setzen Cookies vor allem, um die Vorlieben des Benutzers zu speichern.

Cookies sind in RFC 2109 – HTTP State Management Mechanism definiert, stammen aus der CGI-Programmierung und können neben CGI und Javascript auch von PHP gesetzt und gelesen werden.

Desktop-Anwendungen haben einen Zustand: Sie erinnern sich, welche Dokumente zuletzt geöffnet waren, wo welche Werkzeugleisten saßen und welche Schrift wir am liebsten benutzen.

Das HTTP-Protokoll ist zustandslos. Auch wenn wir zum zweiten, dritten Mal oder hundertsten Mal auf eine Webseite kommen, erinnert sich die HTML-Seite nicht an uns. Ohne Cookies müssten wir uns jedesmal und auf jeder Seite bei Facebook und Twitter anmelden. Niemals würde sich der eigene Blog merken, dass wir angemeldet sind und lieber ohne grafischen Editor arbeiten.

document.cookie = "button=none;showtools=1;imgsize=medium;lastpost=234;expires=date";

document.cookie erzeugt, liest und löscht Cookies, die ein Gedächtnis für die Anwendung bilden: für das Nutzerverhalten, Warenkörbe, Login-Daten und individuelle Einstellungen.

Cookie-Informationen

Cookies sehen aus wie Strings, sind aber Paare aus einem Key und einem Wert, die im Browser des Besuchers gespeichert werden. Wenn wir die Seite später erneut besuchen, liest Javascript im Cookie nach, dass der Besucher sich eingeloggt oder angemeldet hat und zuletzt nach Waffeleisen, Kettensägen oder Javascript Cookies gesucht hat.

domain
Der Domainname der Webseite. Wird ein Cookie auf einer Subdomain wie blog.myhome.me gesetzt, gilt es nur in der Subdomaine. Damit ein Cookie für alle Subdomains einer Domaine gilt, wird domain=myhome.me gesetzt.
max-age
Ersetzt das veralterte expires. Geltungsdauer des Cookies. Wird keine Zeit (in Sekunden, z.B. 60*60*24*3 – 3 Tage) gesetzt, läuft das Cookie ab, sobald der Besucher den Browser schließt.
path
Der Pfad zur Seite, die das Cookie setzt. Normalerweise gelten Cookie für Webseiten im aktuellen Verzeichnis und deren Unterverzeichnisse. Ein Cookie, das von myhome.me/archiv/page.html gesetzt wird, gilt also auch für myhome.me/archiv/andereseite.html und für myhome.me/archiv/daily/hierauch.html, aber nicht für myhome.me/tags/hiernicht.html. Wenn der Pfad nicht gesetzt wird oder path=/, kann das Cookie von jeder URL der Seite gelesen werden.
secure
Wenn der Wert den String secure enthält, kann das Cookie nur von einem sicheren Server gelesen werden. Bleibt das Feld leer, gibt es keine Einschränkung.
expires
Das alte Format des Ablaufdatums ist überflüssig, wird aber noch von allen Browsern unterstützt. Anstelle von expires ist das einfachere max-age getreten.

Third Party Cookies

Nur die Seite, die ein Cookie gesetzt hat, kann das Cookie lesen. Per Voreinstellung der meisten Browser kann nur eine Seite, die wir besuchen, ein Cookie im Browser des Besuchers hinterlassen. Cookies von Dritten (Third Party Cookies) – typischerweise die Werbung auf der besuchten Seite oder der Versuch des Online Trackings durch Dritte – schließen die Browser automatisch aus.

Session Cookies und Persistent Cookies

Wenn das Cookie kein Ablaufdatum (max-age oder expires) hat, wird es als Session Cookie bezeichnet. Session Cookies werden nicht auf die Festplatte des Benutzers übertragen. Sobald das Browserfenster geschlossen wird, ist das Cookie beim Besucher vergessen.

Session-Cookies können auch gesetzt werden, wenn Cookies im Browser des Besuchers deaktivert sind und werden gesetzt, wenn das Cookie am Ende der Sitzung gelöscht und vergessen werden soll. Das passiert z.B. beim Online-Banking, damit niemand nach dem Schließen des Browserfensters die Session wieder aufnehmen und Transaktionen durchführen kann.

In einem Session-Cookie sitzt meist nur eine Session-Kennung wie yuho23991uuyiao93, die möglichst lang und möglichst zufällig ist. Die Daten zur Session werden anhand der Session-ID auf dem Server gespeichert.

Persistent Cookies hingegen werden im Browser des Besuchers gespeichert, bis der Besucher sie manuell löscht oder ihre Zeit abgelaufen (expires) ist.

Cookies erzeugen

Javascript setzt das Cookie in die Eigenschaft cookie des document-Objekts als Zeichenkette. Cookies haben keine Eigenschaft und keine Methoden, also ist alles Handarbeit, wenn keine Library zugeschaltet wird.

document.cookie="theme=blue twenty; max-age=180; path=/; domain=myhome.me"
  • Nach einem Name-Wert-Paar steht ein Semikolon, gefolgt von einem Leerzeichen,
  • gefolgt von der Geltungsdauer max-age, Semikolon, wieder gefolgt von einem Leerzeichen,
  • am Ende steht der Domainpad.

Die Werte von Cookies dürfen keine Semikolons, keine Kommas oder Leerzeichen – Blanks – enthalten. Darum codiert man den Wert vor dem Speichern im Cookie mit Javascript encodeURIComponent(). Bevor das Cookie gelesen werden kann, muss es mit decodeURIComponent() decodiert werden.

Javascript-Cookies mögen zwar aussehen wie Strings, sind aber keine Strings. Wird ein weiteres Cookie gesetzt:

document.cookie = 'nickname=Emmchen; max-age=+60*60*24*30+ ; path=/";

dann überschreibt dieses Cookie das erste Cookie nicht. Wäre document.cookie ein String, wäre das erste Cookie überschrieben worden. Wird es aber nicht …

Cookies lesen

Beim Auslesen verhält sich document.cookie dann aber doch wie ein String und nur eine Suche im Cookie-String bringt einen bestimmten Cookie-Wert zutage.

var myCookies = document.cookie;

Mal sehen, was diese Seite so hinterlässt?

document.getElementById('showCookie').onclick = function () {
   var ca = document.cookie.split(';');
   var showCookie = ""; 
   for (var i=0; i<ca.length; i++) {
      single = ca[i].split('=');
      showCookie += '<div><b>' + single[0] + '</b> ' +  
      decodeURIComponent(single[1]) + '</div>';
   }
   document.getElementById('youCookie').innerHTML = showCookie;
}

Wenn Javascript das erwartete Cookie nicht findet, gibt das Script einen leeren String zurück. Das passiert z.B., wenn der Besucher die Cookies in seinem Browser gelöscht hat.

Cookies löschen

Um ein Cookie zu löschen, setzt man einen Zeitpunkt in der Vergangenheit. Der Browser sieht darin das abgelaufene Cookie und löscht es aus seinen Speicher.

Man merkt der Cookie-Syntax und den Methoden an, dass Cookies eine alte Technik sind (1997!), zwar nicht besonders kompliziert, aber reichlich angestaubt.

Kompliziert ist allenfalls das Ablaufdatum. Alles beginnt mit dem aktuellen Zeitpunkt – date.getTime():

var date = new Date();
date.setTime (date.getTime() + days * 24 * 60* 60 * 1000);
                                ^     ^
                                |     |
                                |     +-- Tage in Millisekunden umsetzen
                                |
                                +--- Tage bis zum Ablaufdatum
var expires = date.toGMTString();

Viel einfacher funktioniert das Löschen des Javascript-Cookies mit dem neueren max-age: max-age=0

document.cookie = "theme=twenty; max-age=0; path=/; domain=myhome.me"

Cookies enabled?

Das Script testet, ob Cookies deaktiviert oder erlaubt sind und setzt dann ein Cookie als finalen Check, ob das gerade erzeugte Cookie existiert.

function cookiesEnabled () {
    var cookieEnabled = (navigator.cookieEnabled) ? true : false;

    if (typeof navigator.cookieEnabled == "undefined" && !cookieEnabled) { 
        document.cookie="testcookie";
        cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
    }
    return (cookieEnabled);
}

Und was ist, wenn der Benutzer Javascript deaktiviert hat?

Es gibt noch das noscript-Tag für alternatives Markup und Inhalt, die angezeigt werden, wenn der Benutzer Javascript deaktiviert hat.

Auch in PHP kann geprüft werden, ob Cookies erlaubt oder deaktivert sind.

<?php
error_reporting (E_ALL ^ E_WARNING ^ E_NOTICE);

// Wurde das Test-Cookie schon gesetzt?
if ($_GET["set"] != "yes") {
	// Cookie setzen
	setcookie ("test", "test", time() + 60);

	// Seite neu laden
	header ("Location: cookies.php?set=yes");
	
} else { 
	if (!empty($_COOKIE["test"])) {
		echo "Cookies sind in diesem Browser erlaubt";
	} else { 
		echo "Cookies sind in diesem Browser deaktiviert";
	}
}

Cookies ohne Javascript?

Cookies können auch mit einfachem HTML erzeugt werden.

<meta http-equiv="set-cookie" content="myCookie=Ich%20bin%20ein%20Cookie%20ohne%20Javascript">

Mehr zu Cookies ohne Javascript Setting a Cookie Using Only HTML

Und PHP kann natürlich ebenfalls Cookies setzen:

setcookie(name, value, expire, path, domain, secure, httponly);

Cookies mit httponly können nicht mit Javascript gelesen werden, eine Sicherheitsvorkehrung gegen Cross Site Scripting (XSS).

Local Storage und Session Storage

Im Grunde genommen – so sagt der Standard –, sollten Browser weder die Zahl der Cookies noch ihre Größe beschränken soweit es der Speicher des Browsers zulässt. Die Nutzlast von Cookies beträgt mindestens 4 KB und ein Browser soll mindestens 300 Cookies speichern, mindestens 20 Cookies per Host oder Domainname (HTTP State Management Mechanism). Wer sich die Cookies in seinem Browser vornimmt, stellt fest, dass sich schon Hunderte von Cookies unter dem Buchstaben "A" versammeln.

Das Auslesen von Cookies führt zu einem aufwändigen Transfer zwischen dem Browser und dem Server. Die eigentlichen Daten werden bei vielen Vorgängen ja nicht im Cookie selber gespeichert, sondern im Cookie liegt meist nur der Verweis auf Daten in einer Datenbank auf dem Server.

Da aber der Informationsaustausch zwischen dem Script und der Anwendung fundamental ist, setzt HTML5 auf ein neues Konzept: Local Storage und Session Storage ersetzen die altbackenen Cookies durch einen Speicher im Browser des Benutzers und beenden den unverschlüsselten Verkehr zwischen Browser und Server.

Javascript Cookies