Mir ist aufgefallen, dass einige Browser (insbesondere Firefox und Opera) sehr eifrig zwischengespeicherte Kopien von .css- und .js-Dateien verwenden, auch zwischen Browser-Sitzungen. Dies führt zu einem Problem, wenn Sie eine dieser Dateien aktualisieren, aber der Browser des Benutzers weiterhin die zwischengespeicherte Kopie verwendet.
Die Frage ist: Wie kann man den Browser des Benutzers am elegantesten dazu zwingen, die Datei neu zu laden, wenn sie sich geändert hat?
Idealerweise würde die Lösung den Browser nicht dazu zwingen, die Datei bei jedem Besuch der Seite neu zu laden. Ich werde meine eigene Lösung als Antwort posten, aber ich bin neugierig, ob jemand eine bessere Lösung hat, und ich werde Ihre Stimmen entscheiden lassen.
Aktualisierung :
Nachdem ich die Diskussion hier eine Zeit lang zugelassen habe, habe ich den Vorschlag von John Millikin und da5id'für nützlich befunden. Es hat sich herausgestellt, dass es einen Begriff dafür gibt: Auto-Versionierung.
Ich habe unten eine neue Antwort veröffentlicht, die eine Kombination aus meiner ursprünglichen Lösung und Johns Vorschlag ist.
Eine andere Idee, die von SCdF vorgeschlagen wurde, wäre, einen falschen Abfrage-String an die Datei anzuhängen. (Ein Python-Code zur automatischen Verwendung des Zeitstempels als gefälschte Abfragezeichenfolge wurde von pi eingereicht). Es gibt jedoch eine Diskussion darüber, ob der Browser eine Datei mit einem Abfrage-String zwischenspeichern würde oder nicht. (Zur Erinnerung: Wir wollen, dass der Browser die Datei zwischenspeichert und bei zukünftigen Besuchen verwendet. Wir wollen nur, dass er die Datei erneut abruft, wenn sie sich geändert hat).
Da nicht klar ist, was mit einem gefälschten Query-String passiert, akzeptiere ich diese Antwort nicht.
Aktualisierung: Umgeschrieben, um die Vorschläge von John Millikin und da5id zu berücksichtigen. Diese Lösung ist in PHP geschrieben, sollte aber leicht an andere Sprachen angepasst werden können.
Update 2: Einarbeitung der Kommentare von Nick Johnson, dass die ursprüngliche .htaccess
Regex Probleme mit Dateien wie json-1.3.js
verursachen kann. Die Lösung ist, nur zu schreiben, wenn es genau 10 Ziffern am Ende gibt. (Denn 10 Ziffern decken alle Zeitstempel vom 9.9.2001 bis zum 20.11.2286 ab.)
Zunächst verwenden wir die folgende Rewrite-Regel in .htaccess:
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
Nun schreiben wir die folgende PHP-Funktion:
/**
* Given a file, i.e. /css/base.css, replaces it with a string containing the
* file's mtime, i.e. /css/base.1221534296.css.
*
* @param $file The file to be loaded. Must be an absolute path (i.e.
* starting with slash).
*/
function auto_version($file)
{
if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file;
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}
Wo auch immer Sie Ihr CSS einbinden, ändern Sie es wie folgt ab:
<link rel="stylesheet" href="/css/base.css" type="text/css" />
in dies:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
Auf diese Weise müssen Sie den Link-Tag nie wieder ändern, und der Benutzer sieht immer das neueste CSS. Der Browser kann die CSS-Datei zwischenspeichern, aber wenn Sie Änderungen an Ihrem CSS vornehmen, sieht der Browser dies als eine neue URL, so dass er nicht die zwischengespeicherte Kopie verwendet.
Dies kann auch mit Bildern, Favicons und JavaScript funktionieren. Im Grunde alles, was nicht dynamisch erzeugt wird.
Sie können einfach ?foo=1234
an das Ende Ihres css / js-Imports setzen und 1234 in einen beliebigen Wert ändern. Werfen Sie einen Blick auf den SO html-Quelltext für ein Beispiel.
Die Idee dahinter ist, dass die ? Parameter bei der Anfrage sowieso verworfen / ignoriert werden und Sie diese Nummer ändern können, wenn Sie eine neue Version herausbringen.
Anmerkung: Es gibt einige Diskussionen darüber, wie sich dies genau auf das Caching auswirkt. Ich glaube, der allgemeine Tenor ist, dass GET-Anfragen, mit oder ohne Parameter, cachbar sein sollten, so dass die obige Lösung funktionieren sollte.
Es liegt jedoch sowohl am Webserver zu entscheiden, ob er sich an diesen Teil der Spezifikation halten will, als auch am Browser, den der Benutzer verwendet, da er einfach weitermachen und eine neue Version anfordern kann.
Ich habe gehört, dass dies "automatische Versionierung" genannt wird. Die gängigste Methode besteht darin, die mtime der statischen Datei irgendwo in die URL einzubinden und sie mit Hilfe von Rewrite-Handlern oder URL-Confs zu entfernen:
Siehe auch: