it-swarm.com.de

Browser zwingen, den Cache zu löschen

Gibt es eine Möglichkeit, etwas Code auf meiner Seite zu platzieren, damit der Browser-Cache beim Besuch einer Website gelöscht wird und die Änderungen angezeigt werden?

Verwendete Sprachen: ASP.NET, VB.NET und natürlich HTML, CSS und jQuery.

245
Adam

Wenn es sich um .css und .js ändert, besteht eine Möglichkeit zum "Cache-Busting" im Anhängen von etwas wie "_versionNo" an den Dateinamen jeder Version. Zum Beispiel:

script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.

Oder machen Sie es alternativ nach dem Dateinamen:

script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.

Sie können diesen link ausprobieren, um zu sehen, wie es funktionieren könnte.

292
Fermin

Schauen Sie in das cache-control und das verfällt META-Tag.

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">

Eine andere übliche Vorgehensweise ist das Anhängen ständig geänderter Zeichenfolgen an das Ende der angeforderten Dateien. Zum Beispiel:

<script type="text/javascript" src="main.js?v=12392823"></script>

92
Sampson

Update 2012

Dies ist eine alte Frage, aber ich denke, es braucht eine aktuellere Antwort, da es jetzt einen Weg gibt, mehr Kontrolle über das Zwischenspeichern von Websites zu haben.

In Offline-Webanwendungen (das ist wirklich jede HTML5-Website) applicationCache.swapCache() kann zum Aktualisieren der zwischengespeicherten Version Ihrer Website verwendet werden, ohne dass die Seite manuell neu geladen werden muss.

Dies ist ein Codebeispiel aus dem Beginner's Guide zur Verwendung des Anwendungscaches on HTML5 Rocks, in dem erläutert wird, wie Benutzer auf die neueste Version Ihrer Site aktualisiert werden:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      if (confirm('A new version of this site is available. Load it?')) {
        window.location.reload();
      }
    } else {
      // Manifest didn't changed. Nothing new to server.
    }
  }, false);

}, false);

Siehe auch Verwendung des Anwendungscaches im Mozilla Developer Network für weitere Informationen.

Update 2016

Die Dinge ändern sich schnell im Web ... Diese Frage wurde 2009 gestellt, und 2012 habe ich ein Update zu einer neuen Methode zur Behandlung des in der Frage beschriebenen Problems veröffentlicht. Weitere 4 Jahre sind vergangen und jetzt scheint es, dass es bereits veraltet ist. Vielen Dank an cgaldiolo für den Hinweis in den Kommentaren.

Ab Juli 2016 enthält der HTML-Standard, Abschnitt 7.9, Offline-Webanwendungen eine Warnung für veraltete Informationen:

Diese Funktion wird gerade von der Webplattform entfernt . (Dies ist ein langer Prozess, der viele Jahre in Anspruch nimmt.) Verwendung eines der Offline-Webanwendungsfeatures werden zu diesem Zeitpunkt dringend empfohlen . Verwenden Sie stattdessen Servicemitarbeiter.

Den Anwendungscache verwenden im Mozilla Developer Network, auf das ich 2012 verwiesen habe:

Veraltet
Diese Funktion wurde aus den Webstandards entfernt . Obwohl einige Browser dies möglicherweise noch unterstützen, wird dies von .__ durchgeführt. fallen gelassen werden Verwenden Sie es nicht in alten oder neuen Projekten. Seiten oder Web-Apps Die Verwendung kann jederzeit unterbrochen werden.

Siehe auch Fehler 1204581 - Hinzufügen einer Verfallsbenachrichtigung für AppCache, wenn der Abruf von Service Worker-Abrufen aktiviert ist .

71
rsp

Nicht so. Eine Methode ist das Senden der entsprechenden Kopfzeilen bei der Bereitstellung von Inhalten, um den Browser zum erneuten Laden zu zwingen:

Sicherstellen, dass eine Webseite nicht in allen Browsern zwischengespeichert wird.

Wenn Sie hier in SO nach "cache header" oder etwas Ähnlichem suchen, finden Sie ASP.NET-spezifische Beispiele.

Eine andere, weniger saubere, aber manchmal einzige Möglichkeit, wenn Sie die Header auf dem Server nicht steuern können, ist das Hinzufügen eines zufälligen GET-Parameters zu der Ressource, die aufgerufen wird:

myimage.gif?random=1923849839
26
Pekka 웃

Für statische Ressourcen Right-Caching wäre Abfrageparameter mit dem Wert jeder Bereitstellung oder Dateiversion zu verwenden. Dadurch wird der Cache nach jeder Bereitstellung gelöscht. 

/Content/css/Site.css?version={FileVersionNumber}

Hier ist ein ASP.NET-MVC-Beispiel.

<link href="@Url.Content("~/Content/Css/Reset.css")[email protected]().Assembly.GetName().Version" rel="stylesheet" type="text/css" />

Vergessen Sie nicht, die Assembly-Version zu aktualisieren.

13

Ich hatte ein ähnliches Problem und so habe ich es gelöst:

  1. In index.html-Datei habe ich Manifest hinzugefügt:

    <html manifest="cache.manifest">
    
  2. In <head> Abschnitt enthaltenes Skript zur Aktualisierung des Cache:

    <script type="text/javascript" src="update_cache.js"></script>
    
  3. In <body> Abschnitt habe ich eine Onload-Funktion eingefügt:

    <body onload="checkForUpdate()">
    
  4. In cache.manifest habe ich alle Dateien eingefügt, die ich zwischenspeichern möchte. Es ist jetzt wichtig, dass es in meinem Fall (Apache) funktioniert, indem der Kommentar "Version" jedes Mal aktualisiert wird. Es ist auch möglich, Dateien mit "? Ver = 001" oder etwas am Ende des Namens zu benennen, aber es ist nicht erforderlich . Wenn Sie nur # version 1.01 ändern, wird das Cache-Aktualisierungsereignis ausgelöst.

    CACHE MANIFEST
    # version 1.01
    style.css
    imgs/logo.png
    #all other files
    

    Es ist wichtig, 1., 2. und 3. Punkte only in index.html einzufügen. Andernfalls

    GET http://foo.bar/resource.ext net::ERR_FAILED
    

    tritt auf, weil jede "untergeordnete" Datei versucht, die Seite zwischenzuspeichern, während die Seite bereits zwischengespeichert ist.

  5. In update_cache.js-Datei habe ich diesen Code eingefügt:

    function checkForUpdate()
    {
        if (window.applicationCache != undefined && window.applicationCache != null)
        {
            window.applicationCache.addEventListener('updateready', updateApplication);
        }
    }
    function updateApplication(event)
    {
        if (window.applicationCache.status != 4) return;
        window.applicationCache.removeEventListener('updateready', updateApplication);
        window.applicationCache.swapCache();
        window.location.reload();
    }
    

Jetzt ändern Sie nur Dateien und im Manifest müssen Sie den Versionskommentar aktualisieren. Beim Besuch der index.html-Seite wird nun der Cache aktualisiert.

Die Teile der Lösung gehören nicht mir, aber ich habe sie über das Internet gefunden und zusammengestellt, damit es funktioniert.

6
Wojtek Mazurek

Ich hatte einen Fall, in dem ich Kunden online fotografieren würde und das Div aktualisieren müsste, wenn ein Foto geändert wird. Der Browser zeigte immer noch das alte Foto. Also habe ich den Hack benutzt, um eine zufällige GET-Variable aufzurufen, die jedes Mal eindeutig sein würde. Hier ist es, wenn es jemandem helfen könnte

<img src="/photos/userid_73.jpg?random=<?php echo Rand() ?>" ...

EDIT Wie von anderen erwähnt, ist das Folgende eine wesentlich effizientere Lösung, da Bilder nur dann neu geladen werden, wenn sie geändert werden, wobei diese Änderung anhand der Dateigröße identifiziert wird:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
6
zeeshan

Bei vielen Antworten fehlt der Punkt - die meisten Entwickler wissen, dass das Deaktivieren des Caches ineffizient ist. Es gibt jedoch viele Situationen, in denen die Effizienz unwichtig ist und das Verhalten des Standardcaches stark beeinträchtigt wird.

Dazu gehören geschachtelte, iterative Skripttests (der große!) Und fehlerhafte Software-Workarounds von Drittanbietern. Keine der hier angegebenen Lösungen ist für solche häufigen Szenarien geeignet. Die meisten Webbrowser sind viel zu aggressives Caching und bieten keine sinnvollen Mittel, um diese Probleme zu vermeiden.

4
John

Das Aktualisieren der URL für die folgenden Arbeiten ist für mich:

/custom.js?id=1

Durch Hinzufügen einer eindeutigen Nummer nach ?id= und Erhöhen für neue Änderungen müssen Benutzer nicht CTRL + F5 drücken, um den Cache zu aktualisieren. Alternativ können Sie Hash- oder String-Version der aktuellen Uhrzeit oder Epoch nach ?id= anhängen.

So etwas wie ?id=1520606295

2
nPcomp
2
S Pangborn

Nicht sicher, ob Ihnen das wirklich helfen könnte, aber so sollte das Caching in jedem Browser funktionieren. Wenn der Browser eine Datei anfordert, sollte er immer eine Anfrage an den Server senden, es sei denn, es gibt einen "Offline" -Modus. Der Server liest einige Parameter wie Änderungsdatum oder Etags. 

Der Server gibt für NOT MODIFIED eine Fehlerantwort zurück und der Browser muss seinen Cache verwenden. Wenn der etag auf dem Server nicht überprüft wird oder das Änderungsdatum unter dem aktuellen Änderungsdatum liegt, sollte der Server den neuen Inhalt mit dem neuen Änderungsdatum oder den etags oder beiden zurückgeben. 

Wenn keine Zwischenspeicherungsdaten an den Browser gesendet werden, ist das Verhalten vermutlich unbestimmt. Der Browser kann eine Datei zwischenspeichern, die nicht sagt, wie sie zwischengespeichert werden. Wenn Sie Caching-Parameter in der Antwort festlegen, werden Ihre Dateien korrekt zwischengespeichert. Der Server gibt dann möglicherweise einen Fehler oder den neuen Inhalt zurück. 

So sollte es gemacht werden. Die Verwendung von Zufallsparametern oder Versionsnummern in URLs ist mehr wie ein Hack als alles andere. 

http://www.checkupdown.com/status/E304.html http: //en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/ 2011/03/last-modified-header-vs-expire-header-vs-etag/

Nach dem Lesen habe ich gesehen, dass es auch ein Verfallsdatum gibt. Wenn Sie ein Problem haben, kann es sein, dass Sie ein Ablaufdatum festgelegt haben. Mit anderen Worten: Wenn der Browser Ihre Datei zwischenspeichert, sollte er, da er ein Ablaufdatum hat, die Datei vor diesem Datum nicht erneut anfordern müssen. Mit anderen Worten, es wird die Datei niemals an den Server anfragen und niemals eine nicht geänderte 304 erhalten. Der Cache wird einfach verwendet, bis das Verfallsdatum erreicht ist oder der Cache gelöscht wurde.

Das ist meine Vermutung, Sie haben ein Verfallsdatum und sollten zuletzt geänderte Etags oder eine Mischung aus all dem verwenden und sicherstellen, dass kein Verfallsdatum vorliegt. 

Wenn die Benutzer dazu neigen, häufig zu aktualisieren, und die Datei nicht viel geändert wird, ist es möglicherweise ratsam, ein großes Ablaufdatum festzulegen. 

Meine 2 Cent!

2

Ich habe diese einfache Lösung implementiert, die für mich funktioniert (noch nicht in der Produktionsumgebung):

function verificarNovaVersio() {
    var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
    $.ajax({
        url: "./versio.txt"
        , dataType: 'text'
        , cache: false
        , contentType: false
        , processData: false
        , type: 'post'
     }).done(function(sVersioFitxer) {
        console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
        if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
            localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
            location.reload(true);
        }
    });
}

Ich habe eine kleine Datei gefunden, in der sich die HTML-Datei befindet:

"versio.txt":

v00.5.0014

Diese Funktion wird auf allen meinen Seiten aufgerufen. Beim Laden wird geprüft, ob der Versionswert von localStorage niedriger als die aktuelle Version ist, und führt einen aus 

location.reload(true);

... um das Laden vom Server statt vom Cache zu erzwingen.

(Natürlich können Sie anstelle von localStorage Cookies oder anderen permanenten Client-Speicher verwenden.)

Ich habe mich für diese Lösung aus Gründen der Einfachheit entschieden, da nur das Beibehalten einer einzelnen Datei "versio.txt" die vollständige Site zum erneuten Laden zwingt.

Die queryString-Methode ist schwer zu implementieren und wird auch zwischengespeichert (wenn Sie von v1.1 zu einer früheren Version wechseln, wird sie aus dem Cache geladen. Dies bedeutet, dass der Cache nicht geleert wird und alle vorherigen Versionen im Cache bleiben).

Ich bin ein kleiner Neuling und würde Ihre professionelle Überprüfung und Überprüfung schätzen, um sicherzustellen, dass meine Methode ein guter Ansatz ist.

Ich hoffe es hilft.

1
Seak

Hier ist die MDSN-Seite zum Festlegen des Cachings in ASP.NET.

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True

If Response.Cache.VaryByParams("Category") Then
   '...
End If
1
Dave Swersky

Browser zwingen, den Cache zu löschen oder korrekte Daten neu zu laden? Ich habe die meisten der in stackoverflow beschriebenen Lösungen ausprobiert, einige funktionieren, aber nach einiger Zeit zwischenspeichert sie schließlich und zeigt das zuvor geladene Skript oder die zuvor geladene Datei an. Gibt es eine andere Möglichkeit, den Cache zu löschen (css, js usw.) und tatsächlich auf allen Browsern funktionieren würde?

Ich habe bisher herausgefunden, dass bestimmte Ressourcen einzeln neu geladen werden können, wenn Sie Datum und Uhrzeit in Ihren Dateien auf dem Server ändern. "Cache leeren" ist nicht so einfach, wie es sein sollte. Anstatt den Cache auf meinen Browsern zu löschen, wurde mir klar, dass durch das "Berühren" der zwischengespeicherten Serverdateien Datum und Uhrzeit der auf dem Server zwischengespeicherten Quelldatei ("Tested on Edge", "Chrome" und "Firefox") tatsächlich geändert werden. Die meisten Browser laden automatisch die meisten Dateien herunter Aktuelle frische Kopie der Inhalte auf Ihrem Server (Code, Grafiken und Multimedia). Ich schlage vor, Sie kopieren nur die aktuellsten Skripts auf dem Server und "do the touch thing" solution, bevor Ihr Programm ausgeführt wird, damit das Datum aller Ihrer Problemdateien auf das aktuellste Datum und die aktuelle Uhrzeit geändert wird lädt eine frische Kopie in Ihren Browser herunter:

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

dann ... der Rest deines Programms ...

Ich habe einige Zeit gebraucht, um dieses Problem zu beheben (da viele Browser sich anders als andere Befehle verhalten, aber sie alle prüfen die Zeit der Dateien und vergleichen sie mit Ihrer heruntergeladenen Kopie in Ihrem Browser, wenn das Datum und die Uhrzeit unterschiedlich sind, wird die Aktualisierung durchgeführt) kann nicht den vermeintlichen richtigen Weg gehen, es gibt immer eine andere brauchbare und bessere Lösung dafür. Beste Grüße und glückliches Camping. Übrigens berühren (); oder Alternativen funktionieren in vielen Programmiersprachen, einschließlich in Javascript bash sh php, und Sie können sie in HTML einschließen oder aufrufen.

0
Luis H Cabrejo

Zusätzlich zum Festlegen von Cache-control: no-cache sollten Sie auch den Expires-Header auf -1 setzen, wenn die lokale Kopie jedes Mal aktualisiert werden soll (einige Versionen von IE scheinen dies zu erfordern).

Siehe HTTP-Cache - Überprüfen Sie den Server und senden Sie immer If-Modified-Since

0
danben

Es gibt einen Trick, der verwendet werden kann. Der Trick besteht darin, einen Parameter/eine Zeichenfolge an den Dateinamen im Skript-Tag anzuhängen und ihn zu ändern, wenn Sie die Datei ändern.

<script src="myfile.js?version=1.0.0"></script>

Der Browser interpretiert die gesamte Zeichenfolge als Dateipfad, auch wenn nach dem "?" sind Parameter. Nun passiert es also, dass das nächste Mal, wenn Sie Ihre Datei aktualisieren, einfach die Nummer im Skript-Tag auf Ihrer Website ändert (Beispiel <script src="myfile.js?version=1.0.1"></script>), und jeder Browser des Benutzers wird sehen, dass sich die Datei geändert hat und eine neue Kopie erhält.

0
Joish