Leeren Sie den Cache in JavaScript

178

Wie lösche ich einen Browser-Cache mit JavaScript?

Wir haben den neuesten JavaScript-Code bereitgestellt, können jedoch den neuesten JavaScript-Code nicht abrufen.

Anmerkung der Redaktion: Diese Frage wird an den folgenden Stellen halb dupliziert, und die Antwort in der ersten der folgenden Fragen ist wahrscheinlich die beste. Diese akzeptierte Antwort ist nicht mehr die ideale Lösung.

Wie kann man den Browser zwingen, zwischengespeicherte CSS / JS-Dateien neu zu laden?

Wie kann ich Clients zwingen, JavaScript-Dateien zu aktualisieren?

Laden Sie lokale Javascript-Quell- / JSON-Daten dynamisch neu

Dylan Brams
quelle
5
Das verwirrt mich: "Wir haben den neuesten Javascript-Code bereitgestellt, aber wir können den neuesten Javascript-Code nicht erhalten"
Instanz von mir
14
Ich denke, Sie meinen, wie Sie Client-Browser dazu zwingen können, Ihre neueste Version von Javascript und nicht deren zwischengespeicherte Version zu verwenden - in diesem Fall benötigen Sie Gregs Antwort. Wenn Sie wissen möchten, wie es in Ihrem eigenen Browser geht, ist dies die Antwort von David Johnstone.
Benjol
4
Ein gängiger Ansatz besteht darin, ?version=xxxüber einen Erstellungsschritt eine an Ihre JS-verknüpften Dateien anzuhängen . Bei jedem neuen Build wird eine neue Version der JS-Datei angefordert.
Juan Mendes
1
@ JuanMendes Das funktioniert nicht immer. Der gleiche Schritt wird empfohlen, wenn Benutzer Probleme haben, das neueste Favicon anzuzeigen. Es ist einfach nicht garantiert zu funktionieren.
uSeRnAmEhAhAhAhAhA

Antworten:

202

Sie können window.location.reload (true) aufrufen , um die aktuelle Seite neu zu laden. Es werden alle zwischengespeicherten Elemente ignoriert und neue Kopien der Seite, des CSS, der Bilder, des JavaScript usw. vom Server abgerufen. Dadurch wird nicht der gesamte Cache geleert, sondern der Cache für die Seite, auf der Sie sich befinden, wird geleert.

Ihre beste Strategie ist jedoch, den Pfad oder Dateinamen wie in verschiedenen anderen Antworten angegeben zu versionieren. Weitere Informationen finden Sie unter Überarbeiten von Dateinamen: Verwenden Sie Querystring nicht aus Gründen, die nicht ?v=nals Versionsschema verwendet werden sollen.

Kevin Hakanson
quelle
6
Wow, danke! Dies funktioniert gut für einen HTML5-Anwendungscache, der auch aus einer cache.manifest-Datei geladen wird. Ich hatte ein altes Manifest, das nicht aus dem Speicher entfernt wurde, sodass in einem Browser, in dem es zwischengespeichert war, keine neueren Dateien angezeigt wurden. Ich habe dies in die Javascript-Konsole eingegeben und gut funktioniert. Vielen Dank!
JayCrossler
2
Aber wenn Sie den Dateinamen ändern, behalten Sie dann nicht alle vorherigen Versionen bei? Andernfalls erhalten Sie viele fehlgeschlagene Versuche von Suchmaschinen und was Sie nicht tun sollten, um die älteren Versionen (oder mit Lesezeichen versehenen / verknüpften Bilder) zu lesen
Rodolfo
1
wie ist das, dass ich nicht daran gedacht habe, tank you
osdamv
1
Entspricht dies dem Klicken des Benutzers auf die Schaltfläche Aktualisieren?
GMsoF
2
@Manuel Der Zugriff auf die Seite wird nur aus dem Cache der genauen URL deaktiviert, auf der Sie location.reload (true) aufgerufen haben. Die ursprüngliche Seite wird niemals aus dem Cache gelöscht, da lediglich ein Zeitstempel an die neue Anforderung angehängt wird. Wenn auf dieser Seite andere asynchrone Aufrufe ausgeführt werden, wird das Caching-Verhalten dieser Anforderungen NICHT deaktiviert. Z.B. Wenn Sie eine Seite mit reload (true) aktualisieren, die HTML lädt, und diese Seite über ein Skript verfügt, das einen zweiten Ajax-Aufruf ausführt, damit mehr HTML auf derselben Seite angezeigt wird, ist bei der zweiten Anforderung das Caching nicht deaktiviert.
J. Schei
114

Sie können den Cache nicht mit Javascript leeren. Eine übliche Methode besteht darin, die Revisionsnummer oder den zuletzt aktualisierten Zeitstempel wie folgt an die Datei anzuhängen:

myscript.123.js

oder

myscript.js?updated=1234567890

Greg
quelle
9
Beachten Sie jedoch, dass viele Proxys eine Datei nicht zwischenspeichern, wenn sie eine Abfragezeichenfolge enthält. Siehe Antwort von Kevin Hakanson .
Chiborg
4
Wie kann ich den Cache leeren, wenn der gesamte HTML-Code zwischengespeichert wurde? Es wird nicht beeinflusst, auch wenn die Versionsnummer wegen zwischengespeicherten HTML hinzugefügt wird. Bitte helfen Sie
Nandakumar
Wenn ich ein Cache-Element nicht löschen kann, warum sagt MDN dann, dass ich es kann? Was vermisse ich? Ich habe versucht, was MDN sagt, aber kein Glück.
Sнаđошƒаӽ
41

Versuchen Sie, die src der JavaScript-Datei zu ändern? Davon:

<script language="JavaScript" src="js/myscript.js"></script>

Dazu:

<script language="JavaScript" src="js/myscript.js?n=1"></script>

Diese Methode sollte Ihren Browser zwingen, eine neue Kopie der JS-Datei zu laden.

Barry Gallagher
quelle
Was macht das n = 1?
KyelJmD
es macht nichts anderes als etwas anderes zu sein. es könnte sein? 12345 oder? Kyle
Oneezy
Also muss auch der Dateiname geändert werden? Oder nur der src-Pfad, der geändert werden muss?
Fred A
20

Abgesehen vom stündlichen oder wöchentlichen Caching können Sie das Cache nach Dateidaten durchführen.

Beispiel (in PHP):

<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>

oder verwenden Sie sogar die Änderungszeit für Dateien:

<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>
Alexandre T.
quelle
3
Kann ich überprüfen, ob ich das richtig verstehe?: Bei Option 1 ändert sich beim Ändern der Datei der md5-Prüfsummen-Hash, wodurch sich die URL ändert. Der Browser sieht eine neue URL und initiiert ein erneutes Laden der Datei. Die an die URL angehängten Get-Daten werden vom Server ignoriert. Wenn das der Fall ist, verdammt schlau.
Colin Brogan
1
Ist MD5-ing auch ein ganzer Dateiprozessor? Ich denke darüber nach, dies für immer CSS- und JS-Dateien zu tun, aber ich würde es hassen, aus diesem Grund einen Treffer für die Servergeschwindigkeit zu sehen.
Colin Brogan
2
Die Verwendung einer Prüfsumme ist eine gute Idee, sollte aber richtig gemacht werden. Wenn Sie jede Anforderung für jede Datei berechnen, wird Ihre Leistung erheblich beeinträchtigt. Querystring eignet sich auch nicht zum Zwischenspeichern, siehe andere Antworten. Die richtige Verwendung besteht darin, eine Prüfsumme (Teil von?) Oder eine Versionsnummer an den Dateinamen anzuhängen und stattdessen diesen neuen Namen zu verwenden (Sie können ein Build-Skript verwenden, um dies bei der Bereitstellung automatisch durchzuführen). Siehe Grunzen , Rev und Usemin .
Frizi
10

Sie können auch erzwingen, dass der Code in PHP jede Stunde wie folgt neu geladen wird:

<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>

oder

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>
Fabien Ménager
quelle
1
Hallo, was bedeutet "v" und "Token"?
GMsoF
4
@GMsoF, das ist nur ein zusätzlicher get-Parameter, der (in diesem Fall) verwendet wird, um dem Browser mitzuteilen, dass es sich um eine "andere" Datei handelt. Damit der Browser die zwischengespeicherte Version verwirft und stattdessen diese lädt. Dies wird häufig mit dem "Datum der letzten Änderung" einer Datei verwendet. Ich hoffe das macht Sinn ;-)
Jelmer
6

Fügen Sie dies am Ende Ihrer Vorlage ein:

var scripts =  document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){ 
   for(var j=0;j<torefreshs;j++){ 
      if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
        new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
        scripts[i].src = new_src; // change src in order to refresh js
      } 
   }
}
yboussard
quelle
1
Bitte geben Sie eine Erklärung zu Ihrer Lösung
Gabriel Espinoza
@GabrielEspinoza lädt er die Dateien mit Javascript neu, wodurch die Caches aktualisiert werden.
Neo Morina
6

versuche es damit

 <script language="JavaScript" src="js/myscript.js"></script>

Dazu:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>
Daniel
quelle
5

Hier ist ein Ausschnitt dessen, was ich für mein aktuelles Projekt verwende.

Von der Steuerung:

if ( IS_DEV ) {
    $this->view->cacheBust = microtime(true);
} else {
    $this->view->cacheBust = file_exists($versionFile) 
        // The version file exists, encode it
        ? urlencode( file_get_contents($versionFile) )
        // Use today's year and week number to still have caching and busting 
        : date("YW");
}

Aus der Sicht:

<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">

Unser Veröffentlichungsprozess generiert eine Datei mit der Versionsnummer des aktuellen Builds. Dies funktioniert durch URL-Codierung dieser Datei und Verwendung als Cache-Buster. Wenn diese Datei nicht vorhanden ist, werden als Failover die Jahres- und Wochennummer verwendet, damit das Caching weiterhin funktioniert, und sie wird mindestens einmal pro Woche aktualisiert.

Dies bietet auch Cache-Busting für jedes Laden von Seiten in der Entwicklungsumgebung, sodass Entwickler sich nicht darum kümmern müssen, den Cache für Ressourcen (Javascript, CSS, Ajax-Aufrufe usw.) zu leeren.

Justin Johnson
quelle
5

oder Sie können einfach die js-Datei von Server zu Server mit file_get_contets lesen und dann den js-Inhalt in den Header einfügen

Albanx
quelle
4

Vielleicht ist das "Löschen des Caches" nicht so einfach, wie es sein sollte. Anstatt den Cache in meinen Browsern zu leeren, wurde mir klar, dass durch "Berühren" der Datei das Datum der auf dem Server zwischengespeicherten Quelldatei (auf Edge, Chrome und Firefox getestet) geändert wird und die meisten Browser automatisch die aktuellste Kopie von herunterladen Was ist auf Ihrem Server (Code, Grafiken und Multimedia). Ich schlage vor, Sie kopieren einfach die aktuellsten Skripte auf den Server und "do the touch thing" -Lösung, bevor Ihr Programm ausgeführt wird. Dadurch wird das Datum aller Ihrer Problemdateien auf das aktuellste Datum und die aktuellste Uhrzeit geändert und anschließend eine neue Kopie heruntergeladen zu Ihrem Browser:

<?php
    touch('/www/control/file1.js');
    touch('/www/control/file2.js');
    touch('/www/control/file2.js');
?>

... der Rest Ihres Programms ...

Ich habe einige Zeit gebraucht, um dieses Problem zu beheben (da viele Browser unterschiedlich auf verschiedene Befehle reagieren, aber alle die Uhrzeit der Dateien überprüfen und mit Ihrer heruntergeladenen Kopie in Ihrem Browser vergleichen, wenn Datum und Uhrzeit unterschiedlich sind, wird die Aktualisierung durchgeführt) kann nicht den vermeintlich richtigen Weg gehen, es gibt immer eine andere brauchbare und bessere Lösung dafür. Beste Grüße und viel Spaß beim Zelten.

Luis H Cabrejo
quelle
1
Ich mag diesen Ansatz, aber vielleicht setze ich ihn im falschen Bereich um? Weiß jemand, wo man dies in einem WordPress-Setup hinzufügt? Ich habe es der Datei functions.php hinzugefügt, mit direkten Links zu den JavaScript- und CSS-Dateien, aber ich musste immer noch hart neu laden, damit die Änderungen bemerkt wurden.
Flipflopmedia
1
Was Sie tun müssen, ist, in Ihrem Haupt-HTML-WordPress-Verzeichnis Ihre index.php zu bearbeiten, um den Befehl Touch () für die Dateien aufzurufen oder auszuführen, die aktualisiert und heruntergeladen werden müssen. Ich hatte Probleme mit kleinen Bildern und JS-Dateien, die im Cache stecken blieben. Ich habe die meisten beschriebenen Methoden ausprobiert, um sie aus dem Speicher freizugeben, aber der beste Weg ist, eine aktuelle, frische, korrekte Methode zu laden. Sie können dies erreichen, indem Sie einfach "Touch Thing" ausführen, da nichts an der Datei geändert wird. Sie aktualisieren lediglich die aktuelle Uhrzeit und das aktuelle Datum, sodass Ihr Browser täuscht, es sei eine andere Version der Datei, und das Problem wurde behoben. Funktioniert mit den meisten Browsern
Luis H Cabrejo
3

Ich hatte einige Probleme mit dem von yboussard vorgeschlagenen Code. Die innere j-Schleife hat nicht funktioniert. Hier ist der geänderte Code, den ich mit Erfolg verwende.

function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
    var scripts = document.getElementsByTagName('script');
    for(var i = 0; i < scripts.length; i++) {
        var aScript = scripts[i];
        for(var j = 0; j < toRefreshList.length; j++) {
            var toRefresh = toRefreshList[j];
            if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
                new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
                // console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
                aScript.src = new_src;
            }
        }
    }
}
Bryan
quelle
3

Wenn Sie PHP verwenden, können Sie:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>
user3573488
quelle
5
Diese Frage wurde nicht nur vor vier Jahren gestellt, sie hatte auch eine bessere Antwort, auch wenn sie nicht akzeptiert wurde.
3
Außerdem würde diese Methode die Datei jedes Mal neu herunterladen, unabhängig von der tatsächlichen Versionsnummer oder den an der Datei vorgenommenen Änderungen, wodurch das Caching effektiv deaktiviert würde.
Antti29
2

Cache.delete () kann für neues Chrome, Firefox und Oper verwendet werden.

Jay Shah
quelle
Ist dies nicht nur ein Teil der Service Workers-API?
BanksySan
@ BanksySan aus den MDN-Dokumenten:You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
Madbreaks
2

Bitte geben Sie keine falschen Informationen an. Die Cache-API ist eine andere Art von Cache als der http-Cache

Der HTTP-Cache wird ausgelöst, wenn der Server die richtigen Header sendet , auf die Sie mit javasvipt nicht zugreifen können.

Die Cache-API hingegen wird ausgelöst, wenn Sie möchten. Dies ist nützlich, wenn Sie mit einem Servicemitarbeiter zusammenarbeiten, damit Sie Anforderungen überschneiden und von diesem Cache-Typ aus beantworten können. Siehe: Abbildung 1 Abbildung 2 Kurs

Sie können diese Techniken verwenden, um immer einen frischen Inhalt für Ihre Benutzer zu haben:

  1. Verwenden Sie location.reload (true) Dies funktioniert bei mir nicht, daher würde ich es nicht empfehlen.
  2. Verwenden Sie die Cache-API , um im Cache zu speichern und die Anforderung mit dem Service Worker zu überschneiden. Seien Sie vorsichtig mit dieser, da der Server die Cache-Header gesendet hat der Browser zuerst aus dem HTTP-Cache antwortet, für die Dateien möchten. und wenn es es nicht findet, wird es an das Netzwerk weitergeleitet, sodass Sie möglicherweise eine alte Datei erhalten
  3. Ändern Sie die URL Ihrer Stactics-Dateien. Ich empfehle Ihnen, sie mit der Änderung des Inhalts Ihrer Dateien zu benennen. Ich verwende md5 und konvertiere sie dann in eine Zeichenfolge und URL-freundlich. Die MD5 ändert sich mit dem Inhalt der Datei kann HTTP-Cache-Header lange genug frei senden

Ich würde die dritte empfehlen see

John Balvin Arien
quelle
1

Ich neige dazu, mein Framework zu versionieren und dann die Versionsnummer auf Skript- und Stilpfade anzuwenden

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>
SpliFF
quelle
3
OP erwähnte Coldfusion nicht.
März
@ VijayDev 404 für Ihren Link
smarber
1
window.parent.caches.delete("call")

Schließen und öffnen Sie den Browser, nachdem Sie den Code in der Konsole ausgeführt haben.

Apoorv
quelle
1
Einige Erklärungen bitte, was ist "Anruf" im obigen Code?
Anand Rockzz
@AnandRockzz es ist nicht möglich, Cache-API ist nur eine neue Art von Cache, die mit Javascipt verwaltet werden kann. Um also etwas von dort zu löschen, haben Sie es zuvor gespeichert, siehe developer.mozilla.org/en-US/docs/ Web / API / Cache
John Balvin Arias
1

Sie können das Browser-Caching auch mit Meta-HTML-Tags deaktivieren. Fügen Sie einfach HTML-Tags in den Kopfbereich ein, um zu vermeiden, dass die Webseite beim Codieren / Testen zwischengespeichert wird. Wenn Sie fertig sind, können Sie die Meta-Tags entfernen.

(im Kopfbereich)

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0"/>

Aktualisieren Sie Ihre Seite, nachdem Sie diese in den Kopf eingefügt haben, und aktualisieren Sie auch den neuen Javascript-Code.

Über diesen Link erhalten Sie weitere Optionen, falls Sie diese benötigen. Http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

oder Sie können einfach eine Schaltfläche wie diese erstellen

<button type="button" onclick="location.reload(true)">Refresh</button>

Es wird aktualisiert und das Zwischenspeichern vermieden. Es wird jedoch auf Ihrer Seite angezeigt, bis Sie den Test abgeschlossen haben. Anschließend können Sie es entfernen. Faust Option ist am besten ich Sache.

alfmonc
quelle
1

Da der Browser denselben Link zwischenspeichert, sollten Sie ein zufälliges Ende der URL hinzufügen. new Date().getTime()eine andere Nummer generieren.

Fügen Sie einfach das new Date().getTime()Ende des Links wie einen Anruf hinzu

'https://stackoverflow.com/questions.php?' + new Date().getTime()

Ausgabe: https://stackoverflow.com/questions.php?1571737901173

EMAM HASAN
quelle
Willkommen bei SO! Ihre Antwort ist unklar. Bitte bearbeiten Sie es. Diese Art von Antworten, basierend auf dem Link, sollte kommentiert werden, falls der Link verschwindet.
David García Bodego