CSS, HTML und Javascript mit {stil}

Javascript Cookies

Session Storage

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.

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

Keine andere Technik des Webs unterliegt so vielen Fehlinterpretationen und hat einen so schlechten Leumund wie Cookies. Dabei gäbe es ohne Cookies nur einen Bruchteil der Anwendungen und Dienste, die wir vom modernen Web erwarten.

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 schon einmal eingeloggt hat und zuletzt nach Kaffeemaschinen, Waffeleisen 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.

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. Die Cookies von Dritten – typischerweise die Werbung auf der besuchten Seite – schließen die Browser automatisch aus.

Cookies erzeugen

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 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, in dem alternatives Markup liegt, 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 mit jQuery

$(document).ready(function(){  
    // Cookie setzen
    $.cookie('my_cookie_name', 'value inside of it');  
  
    // Cookie lesen  
    alert($.cookie('my_cookie_name'));  
  
    // Cookie löschen 
    $.cookie('my_cookie_name', null);  
}); 

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 Milisekunden 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"

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.

Session

Neben Cookies gibt es noch Sessions, die ebenfalls Informationen über den Benutzer speichern. Sessions sind ein abstraktes Konzept und bestehen aus einer Serie von HTTP-Requests und Responses. Das HTTP-Protokoll kennt keine Sessions, sondern Sessions werden durch PHP implementiert.

Während Cookies im Browser des Benutzers gespeichert werden, liegen Session-Informationen auf dem Server.

Sessions bauen auf Cookies auf – dann speichert das Cookie nichts als eine eindeutige Session ID. Bei jedem Aufruf einer Seite sendet der Client sein Session-ID-Cookie und der Server holt sich damit die Informationen zur Session.