Ideale HTTP-Cache-Steuerungsheader für verschiedene Arten von Ressourcen

82

Ich möchte einen minimalen Satz von Headern finden, die mit "allen" Caches und Browsern funktionieren (auch bei Verwendung von HTTPS !).

Auf meiner Website stehen drei Arten von Ressourcen zur Verfügung:

(1) Für immer zwischenspeicherbar (öffentlich / für alle Benutzer gleich)

Beispiel: 0A470E87CC58EE133616F402B5DDFE1C.cache.html ( automatisch von GWT generiert )

  • Diesen Dateien wird automatisch ein neuer Name zugewiesen, wenn sie den Inhalt ändern (basierend auf dem MD5).

  • Sie sollten so weit wie möglich zwischengespeichert werden, auch wenn HTTPS verwendet wird (also nehme ich an, ich sollte festlegen Cache-Control: public, insbesondere für Firefox?)

  • Sie sollten nicht verlangen, dass der Client einen Roundtrip zum Server durchführt, um zu überprüfen, ob sich der Inhalt geändert hat.

(2) Gelegentliche Änderungen (öffentlich / gleich für alle Benutzer)

Beispiele: index.html, mymodule.nocache.js

  • Diese Dateien ändern ihren Inhalt, ohne die URL zu ändern, wenn eine neue Version der Site bereitgestellt wird.

  • Sie können zwischengespeichert werden, benötigen jedoch wahrscheinlich eine Hin- und Rückfahrt, um jedes Mal erneut validiert zu werden.

(3) Individuell für jede Anfrage (privat / benutzerspezifisch)

Beispiel: JSON-Antworten

  • Diese Ressourcen sollten unter keinen Umständen unverschlüsselt auf der Festplatte zwischengespeichert werden. (Außer vielleicht habe ich ein paar spezifische Anfragen, die zwischengespeichert werden könnten.)

Ich habe eine allgemeine Vorstellung davon, welche Header ich wahrscheinlich für jeden Typ verwenden würde, aber es gibt immer etwas, das mir fehlen könnte.

Chris Lercher
quelle
Vielen Dank für Ihre Antworten und die Kommentare und Links. Ich experimentiere immer noch ein bisschen, aber ich denke, ich werde in der Lage sein, eine Lösung abzuleiten!
Chris Lercher
2
Das Erreichen von # 3 ist im Allgemeinen nicht möglich.
EricLaw
Siehe auch: stackoverflow.com/questions/6491789/…
Mikko Rantalainen

Antworten:

90

Ich würde wahrscheinlich diese Einstellungen verwenden:

  1. Cache-Control: max-age=31556926- Darstellungen können von jedem Cache zwischengespeichert werden. Die zwischengespeicherte Darstellung gilt für 1 Jahr als frisch:

    Um eine Antwort als "Nie abläuft" zu markieren, sendet ein Ursprungsserver ein Ablaufdatum ungefähr ein Jahr nach dem Zeitpunkt, an dem die Antwort gesendet wird. HTTP / 1.1-Server DÜRFEN KEINE Ablaufdaten von mehr als einem Jahr in der Zukunft senden .

  2. Cache-Control: no-cache- Repräsentationen dürfen von jedem Cache zwischengespeichert werden. Caches müssen die Anforderung jedoch zur Validierung an den Ursprungsserver senden, bevor eine zwischengespeicherte Kopie freigegeben wird.
  3. Cache-Control: no-store - Caches dürfen die Darstellung unter keinen Umständen zwischenspeichern.

Siehe Mark Nottingham Caching Tutorial für weitere Informationen.

Gumbo
quelle
1
@Gumbo: Eine Sache, bei der ich mir ziemlich sicher bin, ist, dass ich public festlegen muss , wenn Firefox 3+ öffentliche Dateien unter Verwendung von HTTPS auf der Festplatte zwischenspeichern soll: stackoverflow.com/questions/174348/…
Chris Lercher
2
Einige Browser, wie z. B. IE, beginnen, Cache-Control: No-Cache so zu behandeln, als wäre es No-Store. Dies entspricht zwar nicht dem RFC, wird jedoch wissentlich durchgeführt, um den Fehler zu beheben, den VIELE bei der Verwendung von No-Cache begangen haben, um zu verhindern, dass vertrauliche Daten unverschlüsselt auf der Festplatte gespeichert werden.
AviD
1
@chris_l, ich bin über diesen Link passiert: palisade.plynt.com/issues/2008Jul/cache-control-attributes . Ich erinnere mich nicht, wie sich frühere Versionen verhalten haben, obwohl ich denke, dass IE7 dies auch getan hat.
AviD
2
Außerdem benötigt Firefox PUBLIC im Cache-Control nicht mehr, um HTTPS-Ressourcen zwischenzuspeichern. Insgesamt ist es jedoch am besten, Ihre Website zu testen, während Sie den Datenverkehr beobachten, z. B. mit Fiddler.
EricLaw
3
Das Festlegen eines Cache-Steuerwerts von 100 Jahren wird nicht empfohlen. Zunächst empfiehlt die Spezifikation maximal 1 Jahr. Zweitens führt jeder Wert über 68 Jahre zum sofortigen Ablauf für IE8 und darunter: blogs.msdn.com/b/ieinternals/archive/2010/01/26/…
EricLaw
-2

Die Fälle eins und zwei sind tatsächlich dasselbe Szenario. Sie sollten Cache-Control: publiceine URL mit der Build-Nummer / Version der Site festlegen und anschließend generieren, damit Sie über unveränderliche Ressourcen verfügen, die möglicherweise für immer Bestand haben können. Sie möchten den ExpiresHeader auch in Zukunft ein Jahr oder länger festlegen, damit der Client keine Frischeprüfung durchführen muss.

Für Fall 3 können Sie für maximale Flexibilität Folgendes tun:

"Cache-Control", "no-cache, must-revalidate"
"Expires", 0
"Pragma", "no-cache"
Andrew L.
quelle
Unterschiedliche URLs für neue Builds sind wahrscheinlich keine Option: a) Dies würde den Client zwingen, die für immer zwischengespeicherten Dateien erneut herunterzuladen. Sie erhalten eindeutige Namen, um dies zu vermeiden. b) Die Haupt-URL zu meiner Site sollte nur https://www.example.com/c) Ich möchte, dass Lesezeichen immer auf die neueste Version meiner Site verweisen (stellen Sie sich vor, die Lesezeichen für eine Stackoverflow-Frage würden die Build-Nummer der Site enthalten).
Chris Lercher
Hallo Chris, dieser Ansatz wird im Allgemeinen eher für CSS- und JS-Ressourcen als für Dokumente verwendet. Ich bin damit einverstanden, dass dies nicht für Dokumentkennungen gilt. In diesem Fall sollten Sie einfach die Cache-Steuerung public, Last-Modified und etag für die Header festlegen, wodurch jedes Mal eine Aktualitätsprüfung durchgeführt wird und nur ein 304 zurückgesendet wird, wenn keine Änderungen vorgenommen werden seit dem letzten Download. Alternativ können Sie den eigentlichen dynamischen Seiteninhalt auf jeder Seite über JS herunterladen, um die URL beizubehalten und gleichzeitig ein effektives Caching zu ermöglichen.
Andrew L
Ja, das ist so ziemlich die Art und Weise, wie GWT dies für mich erledigt: Meine index.html (ändert sich gelegentlich) enthält mymodule.nocache.js (ändert sich gelegentlich), die automatisch die richtigen, für immer zwischenspeicherbaren Dateien enthält (große Teile von js, GWT verwaltet) Bildbündel, ...) Das einzige, was mir bleibt, ist das Festlegen der richtigen http-Header für jeden Typ. Ich möchte diese Header auf ein Minimum reduzieren, da sie einen großen Prozentsatz des Übertragungsvolumens ausmachen. Brauche ich also zB sowohl Last-Modified als auch ETag etc.?
Chris Lercher
"Läuft ab" muss eigentlich ein Datum sein, nicht die Zahl 0. Es sollte den gleichen Wert wie der Header "Datum" haben. Siehe mnot.net/cache_docs
Luke Hutchison