Wann fordert ein Browser KEINE Datei an den Server an?
Mit anderen Worten, ich habe eine JavaScript-Datei, die geliefert wird. Sein HTTP-Antwortheader hat eine ETag
, Cache-Control: public
und Expires: Tue, 19 Jan 2038 03:14:07 GMT
.
Der Server gibt einen 304
zurück, nachdem der Browser-Cache gefüllt wurde.
Meine Frage ist, warum prüft der Browser überhaupt den Server und bekommt überhaupt einen 304
? Ich möchte nicht, dass der Browser fragt, ob es eine neue Version gibt - er sollte direkt aus dem Browser-Cache geladen werden, ohne nach Änderungen am Server zu suchen, der das Skript bereitstellt.
Welche Kombination von HTTP-Antwortheatern bewerkstelligt dies?
Erstens ist die relevante HTTP-Spezifikation RFC 7234 . Wenn Sie sich die Spezifikation ansehen, werden Sie zwei Dinge bemerken:
Zweitens machst du nichts falsch an deinem Ende. Es steht den Browsern frei, Antworten zwischenzuspeichern und diese zwischengespeicherten Antworten zu verwenden, wenn die von Ihnen zurückgegebenen Header angegeben werden. Der entscheidende Punkt ist in Abschnitt 4 , wo festgestellt wird, dass eine der Bedingungen für die Zustellung einer zwischengespeicherten Antwort darin besteht, dass die Antwort entweder:
frisch (siehe Abschnitt 4.2) oder
dürfen abgestanden serviert werden (siehe Abschnitt 4.2.4), oder
erfolgreich validiert (siehe Abschnitt 4.3).
Da Sie einen Expires
-Header ausspucken, der weit in der Zukunft liegt und der zu diesem Zeitpunkt noch nicht erreicht wurde, ist die Antwort "frisch" und daher ist keine erneute Validierung erforderlich. Sie tun also alles, was die Spezifikation vorschlägt. (Obwohl die Verwendung von Cache-Control: max-age=foo
eine modernere Methode zum Festlegen von Cache-Ablaufzeiten darstellt als die Verwendung des Headers Expires:
.)
Wenn Sie also das Caching-Verhalten des Browsers ändern möchten, haben Sie Pech.
Allerdings sind die Dinge möglicherweise nicht so schlimm, wie Sie denken. Sie sehen wahrscheinlich nur eine Anfrage und 304, weil Sie die Seite in Ihrem Browser beim Testen aktualisieren . Browser behandeln zwischengespeicherte Ressourcen unterschiedlich, je nachdem, wie die Anforderung für sie ausgelöst wurde.
In einem einfachen Test habe ich eine HTML-Seite erstellt, die ein <script>
-Tag, das auf eine JS-Datei verweist, ein <img>
-Tag, das auf ein Bild verweist, und ein <link>
-Tag, das auf ein CSS-Stylesheet verweist, enthielt. Alle diese Dateien wurden auf einem Apache-Server gehostet, der so konfiguriert ist, dass sie mit Folgendem bereitgestellt werden:
Cache-Control: max-age=172800
-HeaderNatürlich wurden alle Ressourcen beim Laden der ersten Seite mit 200 Codes bedient. Beim Testen in Chrome oder Firefox mit den Standardeinstellungen stellte ich Folgendes fest:
Diese Seite gibt an, dass Internet Explorer dasselbe Verhalten aufweist:
Es gibt eine Reihe von Situationen, in denen Internet Explorer überprüfen muss, ob ein zwischengespeicherter Eintrag gültig ist:
- Der zwischengespeicherte Eintrag hat kein Ablaufdatum und auf den Inhalt wird zum ersten Mal in einer Browsersitzung zugegriffen
- Der zwischengespeicherte Eintrag hat ein Ablaufdatum, ist jedoch abgelaufen
- Der Benutzer hat eine Seitenaktualisierung angefordert, indem er auf die Schaltfläche Aktualisieren geklickt oder F5 gedrückt hat
Mit anderen Worten, normalerweise werden diese Verlängerungsanforderungen nur angezeigt, wenn der Benutzer die Seite explizit aktualisiert. Sofern Sie keine besonderen Anforderungen an das Verhalten des Browser-Caches haben, ist dieses Verhalten durchaus vernünftig.
Google und Mozilla haben beide eine Dokumentation zum HTTP-Caching (ich kann auf der MSDN- oder der Apple Developers-Site nichts Vergleichbares finden), aber beide weisen auch nicht auf die Existenz eines Anbieters hin. Spezifische Caching-Header, mit denen die Regeln geändert werden können, die der Browser verwendet, um den Zeitpunkt für die erneute Überprüfung festzulegen. Was Sie tun möchten, ist einfach nicht möglich.
Wenn Sie wirklich mehr Kontrolle über dieses Verhalten benötigen, können Sie in HTML5 Application Cache nachsehen oder Ihre eigene Caching-Logik mit HTML5 Local Storage erstellen, wie dies basket.js tut.
Expires:
oder Cache-Control: max-age=
sollten funktionieren. Haben Sie in den Serverprotokollen bestätigt, dass der Browser tatsächlich Netzwerkanrufe tätigt? Ich habe festgestellt, dass Firebug zum Beispiel eine verwirrende Ausgabe hat, die besagt, dass Sie Remote-Aufrufe machen, wenn Sie tatsächlich den Cache erreichen.
Wenn Sie sich in meinem Boot befinden und eine Angular-App für IIS bereitgestellt haben, stellen Sie sicher, dass Ihre web.config so konfiguriert ist, dass die URL wie folgt korrekt geschrieben wird:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed" />
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/NameOfYourApp_UnderDefaultWebSite/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Notieren Sie sich speziell den Wert von url in
<action type="Rewrite" url="/NameOfYourApp_UnderDefaultWebSite/" />