Frage

Wir arbeiten derzeit an einer privaten Betaversion und sind daher immer noch dabei, relativ schnelle Änderungen vorzunehmen, obwohl wir diesen Prozess natürlich verlangsamen werden, wenn die Nutzung zunimmt.Allerdings besteht ein Problem darin, dass die Client-Browser nach der Veröffentlichung eines Updates mit neuen JavaScript-Dateien immer noch die zwischengespeicherte Version der Datei verwenden und das Update nicht sehen.Natürlich können wir sie bei einem Support-Anruf einfach dazu auffordern, Folgendes zu tun: StrgF5 aktualisieren, um sicherzustellen, dass sie die aktuellen Dateien vom Server erhalten. Es wäre jedoch besser, dies vor diesem Zeitpunkt zu erledigen.

Unser aktueller Gedanke besteht darin, einfach eine Versionsnummer an den Namen der JavaScript-Dateien anzuhängen und dann bei Änderungen die Version im Skript zu erhöhen und alle Referenzen zu aktualisieren.Damit ist die Arbeit auf jeden Fall erledigt, aber die Aktualisierung der Referenzen für jede Veröffentlichung könnte umständlich werden.

Da ich sicher bin, dass wir nicht die ersten sind, die sich damit befassen, dachte ich, ich würde es der Community vorlegen.Wie stellen Sie sicher, dass Clients ihren Cache aktualisieren, wenn Sie Ihren Code aktualisieren?Wenn Sie die oben beschriebene Methode verwenden, verwenden Sie dann einen Prozess, der die Änderung vereinfacht?

War es hilfreich?

Lösung

Soweit ich weiß, besteht eine gängige Lösung darin, a hinzuzufügen ?<version> zum src-Link des Skripts.

Zum Beispiel:

<script type="text/javascript" src="myfile.js?1500"></script>

Ich gehe an dieser Stelle davon aus, dass es keinen besseren Weg als „Suchen-Ersetzen“ gibt, um diese „Versionsnummern“ in allen Skript-Tags zu erhöhen?

Vielleicht lässt das ein Versionskontrollsystem für Sie erledigen?Die meisten Versionskontrollsysteme verfügen beispielsweise über eine Möglichkeit, die Revisionsnummer beim Einchecken automatisch einzufügen.

Es würde ungefähr so ​​aussehen:

<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>

Natürlich gibt es immer bessere Lösungen wie Dieses hier.

Andere Tipps

Das Anhängen der aktuellen Uhrzeit an die URL ist in der Tat eine gängige Lösung.Sie können dies jedoch auch auf Webserverebene verwalten, wenn Sie möchten.Der Server kann so konfiguriert werden, dass er unterschiedliche HTTP-Header für Javascript-Dateien sendet.

Um beispielsweise zu erzwingen, dass die Datei nicht länger als einen Tag zwischengespeichert wird, senden Sie Folgendes:

Cache-Control: max-age=86400, must-revalidate

Wenn Sie in der Betaversion den Benutzer zwingen möchten, immer die neueste Version zu erhalten, verwenden Sie Folgendes:

Cache-Control: no-cache, must-revalidate

Google Page-Speed:Fügen Sie für statische Ressourcen keine Abfragezeichenfolge in die URL ein.Die meisten Proxys, vor allem, die sich durch Version 3.0 befinden, zwischenstreben Sie Ressourcen nicht mit einem "?" in ihrer URL auch wenn eine Cache-Kontrolle:Der öffentliche Header ist in der Antwort vorhanden.Um Proxy-Caching für diese Ressourcen zu aktivieren, entfernen Sie Abfragezeichenfolgen aus Verweisen auf statische Ressourcen und kodieren Sie stattdessen die Parameter in die Dateinamen selbst.

In diesem Fall können Sie die Version in die URL einfügen, z. B.: http://abc.com/v1.2/script.js und verwenden Sie Apache mod_rewrite, um den Link umzuleiten http://abc.com/script.js.Wenn Sie die Version ändern, aktualisiert der Client-Browser die neue Datei.

Diese Verwendung wurde abgelehnt: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

Diese Antwort ist nur 6 Jahre zu spät, aber ich sehe diese Antwort an vielen Stellen nicht ...HTML5 wurde eingeführt Anwendungscache welches zur Lösung dieses Problems verwendet wird.Ich stellte fest, dass der neue Servercode, den ich schrieb, altes, in den Browsern der Leute gespeichertes Javascript zum Absturz brachte, also wollte ich eine Möglichkeit finden, ihr Javascript ablaufen zu lassen.Verwenden Sie eine Manifestdatei, die wie folgt aussieht:

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

und generieren Sie diese Datei jedes Mal mit einem neuen Zeitstempel, wenn Sie möchten, dass Benutzer ihren Cache aktualisieren.Als Randbemerkung: Wenn Sie dies hinzufügen, wird der Browser dies tun nicht neu laden (auch wenn ein Benutzer die Seite aktualisiert), bis das Manifest es dazu auffordert.

Wie wäre es mit dem Hinzufügen der Dateigröße als Ladeparameter?

<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>

Jedes Mal, wenn Sie die Datei aktualisieren, ändert sich der Parameter „filever“.

Wie wäre es, wenn Sie die Datei aktualisieren und Ihr Update zur gleichen Dateigröße führt?Wie hoch sind die Chancen?

Nicht alle Browser speichern Dateien mit '?' drin.Um sicherzustellen, dass es so weit wie möglich zwischengespeichert wurde, habe ich die Version in den Dateinamen aufgenommen.

Also statt stuff.js?123, Ich tat stuff_123.js

ich benutzte mod_redirect(Glaube ich) in Apache zu have stuff_*.js gehen stuff.js

Für ASP.NET-Seiten verwende ich Folgendes

VOR

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

NACH (Neuladen erzwingen)

<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

Das Hinzufügen von DateTime.Now.Ticks funktioniert sehr gut.

Für ASP.NET vermute ich die nächste Lösung mit erweiterten Optionen (Debug-/Release-Modus, Versionen):

Auf diese Weise eingebundene Js- oder CSS-Dateien:

<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />

Global.JsPostfix und Global.CssPostfix werden in Global.asax wie folgt berechnet:

protected void Application_Start(object sender, EventArgs e)
{
    ...
    string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
    bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
    int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
    JsPostfix = "";
#if !DEBUG
    JsPostfix += ".min";
#endif      
    JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
    if (updateEveryAppStart)
    {
        Random rand = new Random();
        JsPosfix += "_" + rand.Next();
    }
    ...
}

Wenn Sie die Seite erstellen, die auf die JS-Dateien verweist, besteht eine einfache Lösung darin, den Zeitstempel der letzten Änderung der Datei an die generierten Links anzuhängen.

Dies ist Huppies Antwort sehr ähnlich, funktioniert aber in Versionskontrollsystemen ohne Schlüsselwortersetzung.Es ist auch besser, als die aktuelle Zeit anzuhängen, da dies das Zwischenspeichern verhindern würde, selbst wenn sich die Datei überhaupt nicht geändert hat.

Wir haben ein SaaS für Benutzer erstellt und ihnen ein Skript zur Verfügung gestellt, das sie auf ihrer Website-Seite anhängen können. Es war jedoch nicht möglich, eine Version mit dem Skript anzuhängen, da der Benutzer das Skript für Funktionalitäten an seine Website anfügt und ich dies nicht erzwingen kann um die Version jedes Mal zu ändern, wenn wir das Skript aktualisieren

Deshalb haben wir eine Möglichkeit gefunden, jedes Mal, wenn der Benutzer das Originalskript aufruft, die neuere Version des Skripts zu laden

Der dem Benutzer bereitgestellte Skript-Link

<script src="https://thesaasdomain.com/somejsfile.js" data-ut="user_token"></script>

die Skriptdatei

if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) {
   init();
} else {
   loadScript("https://thesaasdomain.com/somejsfile.js?" + guid());
}

var loadscript = function(scriptURL) {
   var head = document.getElementsByTagName('head')[0];
   var script = document.createElement('script');
   script.type = 'text/javascript';
   script.src = scriptURL;
   head.appendChild(script);
}

var guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

var init = function() {
    // our main code
}

Erläuterung:

Der Benutzer hat das ihm auf seiner Website bereitgestellte Skript angehängt und wir haben mithilfe des jQuery-Selektors überprüft, ob das mit dem Skript angehängte eindeutige Token vorhanden ist oder nicht. Wenn nicht, laden wir es dynamisch mit einem neueren Token (oder einer neueren Version).

Dies bedeutet, dass dasselbe Skript zweimal aufgerufen wird, was ein Leistungsproblem darstellen kann, aber es löst wirklich das Problem, das Skript dazu zu zwingen, nicht aus dem Cache zu laden, ohne die Version in den tatsächlichen Skript-Link einzufügen, der dem Benutzer oder Client gegeben wird

Haftungsausschluss:Verwenden Sie es nicht, wenn die Leistung in Ihrem Fall ein großes Problem darstellt.

Die jQuery-Funktion getScript kann auch verwendet werden, um sicherzustellen, dass bei jedem Laden der Seite tatsächlich eine js-Datei geladen wird.

So habe ich es gemacht:

$(document).ready(function(){
    $.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
         startProgram();
    });
});

Überprüfen Sie die Funktion unter http://api.jquery.com/jQuery.getScript/

Standardmäßig setzt $.getScript() die Cache-Einstellung auf „false“.Dadurch wird ein zeitgestempelter Abfrageparameter an die Anforderungs-URL angehängt, um sicherzustellen, dass der Browser das Skript bei jeder Anforderung herunterlädt.

Eine Lösung besteht darin, beim Abrufen der Ressource eine Abfragezeichenfolge mit einem Zeitstempel an die URL anzuhängen.Dies macht sich die Tatsache zunutze, dass ein Browser keine Ressourcen zwischenspeichert, die von URLs mit darin enthaltenen Abfragezeichenfolgen abgerufen werden.

Sie möchten jedoch wahrscheinlich nicht, dass der Browser diese Ressourcen überhaupt nicht zwischenspeichert.Es ist wahrscheinlicher, dass Sie sie zwischenspeichern möchten, aber Sie möchten, dass der Browser eine neue Version der Datei abruft, wenn sie verfügbar ist.

Die gebräuchlichste Lösung scheint darin zu bestehen, einen Zeitstempel oder eine Revisionsnummer in den Dateinamen selbst einzubetten.Das ist etwas aufwändiger, da Ihr Code geändert werden muss, um die richtigen Dateien anzufordern, aber es bedeutet, dass z.B.Version 7 von Ihnen snazzy_javascript_file.js (d. h. snazzy_javascript_file_7.js) wird im Browser zwischengespeichert, bis Sie Version 8 veröffentlichen, und dann ändert sich Ihr Code in „fetch“. snazzy_javascript_file_8.js stattdessen.

Verwenden Sie eine Version GET Variable, um Browser-Caching zu verhindern.

Anhängen ?v=AUTO_INCREMENT_VERSION am Ende Ihrer URL verhindert das Zwischenspeichern des Browsers und vermeidet so alle zwischengespeicherten Skripte.

Mein Kollege hat gerade einen Verweis auf diese Methode gefunden, direkt nachdem ich (in Bezug auf CSS) unter gepostet habe http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/.Schön zu sehen, dass andere es verwenden und es zu funktionieren scheint.Ich gehe an dieser Stelle davon aus, dass es keinen besseren Weg als „Suchen-Ersetzen“ gibt, um diese „Versionsnummern“ in allen Skript-Tags zu erhöhen?

Obwohl es Framework-spezifisch ist, hat Django 1.4 dies diese Funktionalität Dies funktioniert ähnlich wie der Link zur „Greenfelt“-Site im obige Antwort

In PHP:

function latest_version($file_name){
    echo $file_name."?".filemtime($_SERVER['DOCUMENT_ROOT'] .$file_name);
}

In HTML:

<script type="text/javascript" src="<?php latest_version('/a-o/javascript/almanacka.js'); ?>">< /script>

Wie es funktioniert:

Schreiben Sie in HTML das filepath und benennen Sie es wie gewohnt, aber nur in der Funktion.PHP bekommt das filetime der Datei und gibt die zurück filepath+name+"?"+time der letzten Änderung

Cache Busting in ASP.NET Core über einen Tag-Helfer erledigt dies für Sie und ermöglicht Ihrem Browser, zwischengespeicherte Skripte/CSS beizubehalten, bis sich die Datei ändert.Fügen Sie einfach den Tag-Helfer asp-append-version="true" zu Ihrem Skript- (JS) oder Link-Tag (CSS) hinzu:

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>

Dave Paquette hat hier (unten auf der Seite) ein gutes Beispiel und eine Erklärung zum Cache-Busting. Cache-Busting

Heutzutage ist es üblich, einen Inhalts-Hash-Code als Teil des Dateinamens zu generieren, um den Browser, insbesondere den IE, zu zwingen, die Javascript- oder CSS-Dateien neu zu laden.

Zum Beispiel,

Verkäufer.a7561fb0e9a071baadb9.js
hauptsächlich.b746e3eb72875af2caa9.js

Dies ist im Allgemeinen die Aufgabe der Build-Tools wie Webpack.Hier ist mehr Einzelheiten Falls jemand ausprobieren möchte, ob Sie Webpack verwenden.

Einfachste Lösung?Lassen Sie den Browser überhaupt nicht zwischenspeichern.Hängen Sie die aktuelle Zeit (in ms) als Abfrage an.

(Sie befinden sich noch in der Betaphase, daher könnten Sie gute Argumente dafür vorbringen, keine Leistungsoptimierung vorzunehmen.Aber YMMV hier.)

Der Vorteil der Verwendung von a file.js?V=1 über ein fileV1.js besteht darin, dass Sie nicht mehrere Versionen der JavaScript-Dateien auf dem Server speichern müssen.

Das Problem sehe ich mit file.js?V=1 besteht darin, dass Sie möglicherweise abhängigen Code in einer anderen JavaScript-Datei haben, der bei Verwendung der neuen Version der Bibliotheksdienstprogramme fehlerhaft ist.

Aus Gründen der Abwärtskompatibilität halte ich die Verwendung für viel besser jQuery.1.3.js für Ihre neuen Seiten und lassen Sie bestehende Seiten nutzen jQuery.1.1.js, bis Sie bereit sind, die älteren Seiten bei Bedarf zu aktualisieren.

Ein einfacher Weg.htaccess bearbeiten

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]

In asp.net können Sie mvc verwenden @DateTime.UtcNow.ToString() für die Versionsnummer der JS-Datei.Die Versionsnummer ändert sich automatisch mit dem Datum und Sie zwingen den Client-Browser, die JS-Datei automatisch zu aktualisieren.Ich verwende diese Methode und sie funktioniert gut.

<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>

Folgendes hat bei mir funktioniert:

<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top