JS: Überlisten Sie den Cache!

von Thomas Salvador.

Im Grunde ist der Cache des Browsers eine wunderbare Sache, spart er doch Zeit und Bandbreite. Seiten und Bilder, allgemeiner Objekte, werden bei der ersten Anforderung aus dem Netz geholt und im folgenden bis zu ihrem Verfallsdatum aus dem Cache.

Objekte werden an ihrem URL identifiziert. Und genau das kann auch zum Problem werden.

Denn nicht immer möchte man, dass etwas aus dem Cache geholt wird, z.B. weil man weiß, dass Sie das Objekt hinter dieser Adresse bereits verändert hat.

Sicher könnte man den Browser konsequent das alter des Objektes hinter dem URL prüfen lassen, doch würde das die Performance drastisch senken (und ist für alle anderen übrigen Objekte überflüssig).

Auch könnte man den Cache komplett abschalten und ein komplettes Neuladen erzwingen.

Das ist nun wahrlich nicht gerade elegant. Schlimmer noch werden dabei viele, viele (nämlich die allermeisten) Objekte immer wieder und völlig überflüssigerweise geladen.

Wie also deaktiviert man den Cache für genau das eine Objekt? Natürlich mit einem Trick, denn direkt ist das nicht möglich.

Wir benötigen dazu eine Scriptsprache. Ich benutze hier JavaScript.

Sagen wir, wir haben ein Bild https://irgendwas.erde/bild.gif. Sei es, dass es von einer WebCam oder von periodisch überschrieben wird.

Wie Sie wissen, kann man JavaScript mit

document.bild.src = "https://irgendwas.erde/bild.gif";

das Laden des Bildes fordern, wenn man das Bild in HTML entsprechend vorbereitet - sprich benannt - hat.

<img src="leer.gif" width="320" height="200" name="bild" />

Das Laden des Bildes muss nun periodisch mit entsprechender Pause erfolgen.

Sagen wir, die WebCam updated alle 10 Minuten (= 600 Sekunden = 600000 Millisekunden). Hier kommt die Timer-Funktion setTimeout() zum Einsatz.

function update() {
  document.bild.src = "https://irgendwas.erde/bild.gif";
  setTimeout("update();", 600000);
}

Angestoßen werden muss das Ganze einmal durch den onload-Event, der ausgelöst wird (man sagt auch "feuert"), wenn das Laden des Dokumentes abgeschlossen ist.

<body ... onLoad="update();">

Gut. So weit, so gut, so falsch. Es wird nicht funktionieren!

Das Bild wird einmal erscheinen, dann aber nicht mehr durch neue ersetzt werden, was – deshalb steht das oben ja alles – daran liegt, dass es dann aus dem Cache kommt.

Die Lösung ist kurz und erscheint einfach (wenn man sie mal gesehen hat – wie meistens). Ersetzen Sie

https://irgendwas.erde/bild.gif

durch

https://irgendwas.erde/bild.gif?xyz

Dabei ist xyz eine Zufallszahl zwischen 0 und 999! Das Bild wird dennoch geladen, aber durch die Zufallszahl ändert sich der URL kontinuierlich, so dass das Bild nicht aus dem Cache geholt wird, da es für den Browser ein ein neues Objekt ist.

Die entsprechend modifizierte Funktion update() sieht nun so aus:

function update() {
  var a= Math.floor(Math.random()*1000);
  document.bild.src = "https://irgendwas.erde/bild.gif?" + a;
  setTimeout("update();", 600000);
}

Diese Methode ist übrigens sehr flexibel. Mit an Sicherheit grenzender Wahrscheinlichkeit kennen Sie Linkexchange oder einen anderen Bannertausch.

Die meisten Bannertausche arbeiten mit SeitenCodes (PageCodes, SubCodes). Hat man einen SSI-Server lässt man das eben generieren, ist ja nicht das Problem.

Hat man aber keinen, muss man da selbst Hand anlegen und auf den einzelnen Seiten verschiedene Bannercodes einfügen.

Wenn nicht, muss man dass von Hand machen.

Was für ein paar Pages noch witzig ist, kann einem doch wirklich schnell auf die Nerven gehen. Einfacher ist es, wenn man den BannerCode durch JavaScript o.ä. on-the-Fly generieren lässt anstelle des PageCodes setzt man die Zufallszahl.

Dies hat noch den Vorteil, dass jemand, der eine Seite ein zweites Mal abruft (z.B. per Back-Taste), auch einen neuen Banner bekommt.

Natürlich gibt es auch bei dieser "Zufallszahl" Duplikate, für die dan der alte Banner für diese Zahl gezeigt werden würde. Es ist nur unwahrscheinlicher.

Verhindern können Sie das, wenn Sie etwas wählen, was sich definitiv geändert hat. Richtig, Zeit.

function update() {
  var a= (new Date()).getTime();
  document.bild.src = "https://irgendwas.erde/bild.gif?" + a;
  setTimeout("update();", 600000);
}

Freilich können Sie dann keine genaue Seitenstatistik mehr durchführen. Man muss aber ein Script auch nicht auf jeder Seite einsetzen und kann auf den Seiten, die man tracken möchte spezielle Werte (hier z.B. >1000) nutzen.