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 Vorlieben des Benutzers zu speichern, für Warenkörbe und um wiederkehrende Benutzer zu erkennen.

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 erinnern sich, welches Dokument zuletzt geöffnet war, 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.

                   Name, Schlüssel      Wert           max. Speicherzeit   Pfad          Cookie-Domaine
                         +                +                    +             +                 +
                         |                |                    |             |                 |
document.cookie = "lastPosition=" + cookieValue + "; max-age=60*60*24*3; path=/; domain=www.meineseite.de";

document.cookie erzeugt, liest und löscht Cookies, die ein Gedächtnis für die Anwendung bilden: für das Nutzerverhalten, Warenkörbe und individuelle Einstellungen. Cookies speichern bis zu 4KB, und entsprechend der Spezifikation RFC 6265 soll ein Browser bis zu 3000 Cookies speichern.

Cookie-Informationen

Cookies sehen aus wie Strings, sind aber Paare aus einem Schlüssel oder Namen 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.

comment (optional)
Kann den Benutzer über die Nutzung des Cookies aufklären.
domain (optional)
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.
Wenn der Domainname angegeben wird, muss die Domain mit mindestens zwei Punkten geschrieben werden. Ist die URL z.B. www.meineseite.de, muss der Domainname mit .meineseite.de oder buch.meineseite.de angegeben werden.
max-age
Ersetzt das veraltete 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.
version (dezimal, ganzzahlig)
Version der Cookie-Spezifikation (version=1)
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 auslesen. 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=86400; path=/; domain=myhome.me"
  • Nach einem Name-Wert-Paar steht ein Semikolon, evtl. gefolgt von einem Leerzeichen,
  • gefolgt von der Geltungsdauer max-age, Semikolon, wieder evtl. gefolgt von einem Leerzeichen,
  • am Ende stehen der Cookie-Pfad und die Cookie-Domaine.

Der Name des Cookies ist natürlich erforderlich und darf kein Semikolon, Gleichheitszeichen, Komma oder Blank (Leerzeichen) enthalten. Der Cookie-Wert hingegen ist optional. meincookie=; ist also korrekt.

Die Werte von Cookies dürfen kein Semikolon, kein Komma oder Leerzeichen 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.

Cookies überschreiben

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

document.cookie = 'nickname=Entchen; 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 … Stattdessen sammeln sich Cookies im Cookie-String und beim Auslesen eines bestimmten Cookies muss der Name des Cookies ausgefiltert werden.

Nur ein zweites Cookie mit demselben Namen, Pfad und Domain würde das erste Cookie überschreiben. Unterscheiden sich hingegen Pfad oder Domain, dann existieren zwei Cookies mit demselben Namen. Das wird wohl selten so gewollt sein.

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, das angezeigt wird, 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 konnten zurvor auch mit einfachem HTML im einem Meta-Tag mit dem http-equiv-Attribut 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). Google Chrome 65 hat den Support für http-equiv="set-cookie" bereits im März 2018 fallen lassen und Firefox will diesem Beispiel folgen.

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