Was bewirkt das Anhängen von "? V = 1" an CSS- und Javascript-URLs in Link- und Skript-Tags?

138

Ich habe mir eine HTML 5-Boilerplate-Vorlage (von http://html5boilerplate.com/ ) angesehen und festgestellt, dass "?v=1"URLs verwendet werden, wenn auf CSS- und Javascript-Dateien verwiesen wird.

  1. Was bewirkt das Anhängen "?v=1"an CSS- und Javascript-URLs in Link- und Skript-Tags?
  2. Nicht alle Javascript-URLs haben das "?v=1"(Beispiel aus dem folgenden Beispiel :) js/modernizr-1.5.min.js. Gibt es einen Grund, warum dies der Fall ist?

Probe aus ihrem index.html:

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->
maxyfc
quelle

Antworten:

175

Diese dienen normalerweise dazu, sicherzustellen, dass der Browser eine neue Version erhält, wenn die Site mit einer neuen Version aktualisiert wird, z. B. als Teil unseres Erstellungsprozesses hätten wir ungefähr Folgendes:

/Resources/Combined.css?v=x.x.x.buildnumber

Da sich dies mit jedem neuen Code-Push ändert, muss der Client aufgrund des Querystrings eine neue Version abrufen. Schauen Sie sich diese Seite (zum Zeitpunkt dieser Antwort) zum Beispiel an:

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

Ich denke, anstelle einer Revisionsnummer hat das SO-Team einen Datei-Hash verwendet. Dies ist ein noch besserer Ansatz, selbst bei einer neuen Version mussten die Browser nur dann eine neue Version abrufen, wenn sich die Datei tatsächlich ändert.

Mit beiden Ansätzen können Sie den Cache-Header auf einen lächerlich langen Wert einstellen, beispielsweise 20 Jahre. Wenn er sich jedoch ändert, müssen Sie sich keine Gedanken über diesen Cache-Header machen. Der Browser sieht einen anderen Querystring und behandelt ihn als andere, neue Datei.

Nick Craver
quelle
3
@Free - Ein gestern gesendeter Cache-Steuerungsheader kann dem Client nicht mitteilen, dass die Datei heute geändert wurde (der Client überprüft sie nicht einmal). Eine URL kann dies. Können Sie erklären, was ich dort vermisse?
Nick Craver
8
@Free - Die Art und Weise, wie diese Dateien zwischengespeichert werden, ist für immer , was bedeutet, dass der Client in keiner Weise prüft, ob die Datei geändert wurde. Dies bedeutet, dass sie die aktualisierte Datei niemals erhalten würden ... es sei denn, die URL wurde geändert, was mit der obigen Technik geschieht. Sie erhalten eine maximale Cache-Lebensdauer auf dem Client (wenige HTTP-Anforderungen), aber der Client wird sofort aktualisiert, wenn sich die Datei tatsächlich ändert . Wie genau würden Sie all dies erreichen, wenn Sie nur Cache-Steuerungsheader verwenden?
Nick Craver
4
@Free - Stack Overflow verzeichnet monatlich 5 Millionen Besucher, Ihr Ansatz hätte zwei Auswirkungen: a) viel mehr Anfragen und Daten, die an / von unseren Servern gesendet werden, und b) die Benutzer würden nicht sofort neues JavaScript / CSS erhalten (zum Beispiel) wenn wir einen Fehler hatten oder die HTML-Änderungen neues JS / CSS benötigten). Natürliches Ablaufen ist hier wirklich keine Option. Die von Ihnen vorgeschlagene Methode wäre technisch viel weniger effizient und führt regelmäßig zu tatsächlichen Benutzerfehlern. Dies ist auf keiner größeren Site wirklich akzeptabel (und sollte auch auf keiner Site wirklich der Fall sein ).
Nick Craver
2
@Free - Die 5 Millionen sind 5 Millionen Besucher pro Monat , da wir mehrmals am Tag bereitstellen , sind die Anforderungen um ein Vielfaches höher . In Bezug auf das Laden von HTML-Seiten sprechen wir von etwas mehr als 110 Millionen pro Monat (und das Wachstum ... wieder sind es nur das Laden von HTML-Seiten). Für a) ja, viel mehr oder mehr Pausen ist es ein Kompromiss zwischen der Cache-Zeit und Clients mit korrektem Inhalt. Außerdem ist Ihre Logik für b) fehlerhaft, das HTML wird nicht zwischengespeichert. Wenn es also mit zwischengespeichertem JS verwendet wird und nicht mehr funktioniert, sind nur zwischengespeicherte Benutzer betroffen, nicht dass sie immun sind.
Nick Craver
5
@GMsoF v stellt für uns nur "Version" dar, es ist eine völlig willkürliche Wahl. Jede Wertabfragezeichenfolge würde funktionieren, z. B. könnte es genauso gut sein? Jejdutogjesudo =
Nick Craver
23

Dadurch wird sichergestellt, dass Sie die neueste Version der CSS- oder JS-Datei vom Server erhalten.

Und später können Sie anhängen, "?v=2"wenn Sie eine neuere Version haben "?v=3", "?v=4"und so weiter.

Beachten Sie, dass Sie jedes verwenden können querystring. 'V' ist beispielsweise kein Muss:

"?blah=1"wird auch funktionieren.

Und

"?xyz=1002" wird funktionieren.

Dies ist eine gängige Technik, da Browser jetzt JS- und CSS-Dateien besser und länger zwischenspeichern.

Amr Elgarhy
quelle
13

Die Hash-Lösung ist nett, aber nicht wirklich lesbar, wenn Sie wissen möchten, welche Version der Datei sich in Ihrem lokalen Webordner befindet. Die Lösung besteht darin, date/timeIhre Version zu stempeln, damit Sie sie leicht mit Ihrer Serverdatei vergleichen können.

Wenn Ihre .js or .cssDatei beispielsweise datiert ist 2011-02-08 15:55:30(letzte Änderung), sollte die Version gleich sein.js?v=20110208155530

Sollte leicht lesbar sein Eigenschaften einer Datei in einer beliebigen Sprache. In ASP.Net ist es wirklich einfach ...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

Natürlich bekommen Sie es zuerst schön in Eigenschaften / Funktionen umgestaltet und los geht's. Keine weiteren Entschuldigungen.

Viel Glück, Art.

Kunst
quelle
2
Was ist, wenn Sie Ihre Website nur mit HTML-JS und CSS erstellen? Wie können wir dann automatisch Versionsnamen in statische Ressourcen einfügen?
Nishanth Nair
@ Whizkid747 späte Antwort, aber für Neulinge sollte jedes Site Builder / Build-System, das Sie verwenden, eine Möglichkeit haben, das Datum in Millisekunden zu ermitteln, das Sie als Version verwenden können, andernfalls, wenn Sie kein Builder // Build-System verwenden Sie müssten diese selbst schreiben.
AntK
7

Javascript-Dateien werden vom Browser häufig viel länger zwischengespeichert, als Sie vielleicht erwarten.

Dies kann häufig zu unerwartetem Verhalten führen, wenn Sie eine neue Version Ihrer JS-Datei veröffentlichen.

Daher ist es üblich, der URL für die Javascript-Datei einen QueryString-Parameter hinzuzufügen. Auf diese Weise speichert der Browser die Javascript-Datei mit v = 1 zwischen. Wenn Sie eine neue Version Ihrer Javascript-Datei veröffentlichen, ändern Sie die URLs in v = 2 und der Browser wird gezwungen, eine neue Kopie herunterzuladen.

Robin Day
quelle
welche Browser genau? Selbst die meisten skurrilen IE 5 und 6 gehorchten den Cache-Steuerungs-Headern.
Kostenlose Beratung
7

Um Ihnen Fragen zu beantworten;

"? v = 1" Dies wird nur geschrieben, um eine neue Kopie der CSS- und JS-Dateien herunterzuladen, anstatt sie aus dem Cache des Browsers zu verwenden.

Wenn Sie diesen Abfragezeichenfolgenparameter am Ende Ihres Stylesheets oder der js-Datei erwähnen, wird der Browser gezwungen, eine neue Datei herunterzuladen. Dadurch werden die letzten Änderungen in den CSS- und JS-Dateien in Ihrem Browser wirksam.

Wenn Sie diese Versionierung nicht verwenden, müssen Sie möglicherweise den Cache zum Aktualisieren der Seite leeren, um die letzten Änderungen in diesen Dateien anzuzeigen.

In diesem Artikel wird erläutert, wie und warum CSS- und JS-Dateien versioniert werden

Tapan Kumar
quelle
2

Während der Entwicklung / des Testens neuer Versionen kann der Cache ein Problem sein, da der Browser, der Server und manchmal sogar die 3G-Telekommunikation (wenn Sie eine mobile Bereitstellung durchführen) den statischen Inhalt (z. B. JS, CSS, HTML, img) zwischenspeichern. Sie können dies überwinden, indem Sie der URL eine Versionsnummer, eine Zufallszahl oder einen Zeitstempel hinzufügen, z. B.: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

Wenn Sie reines HTML ausführen (anstelle von Serverseiten JSP, ASP, PHP), hilft Ihnen der Server nicht weiter. Im Browser werden Links geladen, bevor JS ausgeführt wird. Daher müssen Sie die Links entfernen und mit JS laden.

// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];   
for (i=0; i < cacheBust.length; i++){
     var el = document.createElement('script');
     el.src = cacheBust[i]+"?v=" + Math.random();
     document.getElementsByTagName('head')[0].appendChild(el);
}
Conete Cristian
quelle
0

Wie Sie zuvor lesen können, ?v=1stellt das sicher, dass Ihr Browser die Version 1 der Datei erhält. Wenn Sie eine neue Version haben, müssen Sie nur eine andere Versionsnummer anhängen, und der Browser vergisst die alte Version und lädt die neue.

Es gibt ein gulp- Plugin, das sich um die Version Ihrer Dateien während der Erstellungsphase kümmert, sodass Sie dies nicht manuell tun müssen. Es ist praktisch und kann problemlos in Ihren Erstellungsprozess integriert werden. Hier ist der Link: gulp-annotate

Phugo
quelle
-2

Wie von anderen erwähnt, wird dies für das Front-End-Cache-Busting verwendet. Um dies zu implementieren, habe ich persönlich das Grunt-Cache-Bust-npm-Paket nützlich gefunden.

RAM
quelle
1
Während dieser Link möglicherweise die Frage beantwortet, werden bei Stack Overflow von Antworten nur auf Links abgeraten. Sie können diese Antwort verbessern, indem Sie wichtige Teile des Links in Ihre Antwort aufnehmen. Dadurch wird sichergestellt, dass Ihre Antwort immer noch eine Antwort ist, wenn der Link geändert wird oder entfernt :)
WhatsThePoint