Wenn ich chesseng.herokuapp.com besuche, erhalte ich einen Antwortheader , der aussieht
Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss
und dann aktualisiere ich die Seite und bekomme
Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss
Es scheint also, als würde das Caching funktionieren. Wenn dies für das Caching funktioniert, worum geht es dann bei Expires und Cache-Control: max-age . Wenn ich die Seite unter https://developers.google.com/speed/pagespeed/insights/ teste , wird ich aufgefordert, das Browser-Caching zu nutzen.
http
caching
http-headers
browser-cache
cache-control
user782220
quelle
quelle
Antworten:
Um Ihre Frage zu beantworten, warum das Caching funktioniert, obwohl der Webserver die Header nicht enthielt:
[a date]
[seconds]
Der Server hat alle Zwischenproxys gebeten, den Inhalt nicht zwischenzuspeichern (dh das Element sollte nur in einem privaten Cache zwischengespeichert werden, dh nur auf Ihrem eigenen lokalen Computer):
Der Server hat jedoch vergessen, Caching-Hinweise anzugeben:
Die Antwort enthielt jedoch ein Datum der letzten Änderung :
Da der Browser das Datum kennt, an dem die Datei geändert wurde, kann er eine bedingte Anforderung ausführen . Der Server wird nach der Datei gefragt, der Server wird jedoch angewiesen, die Datei nur zu senden, wenn sie seit dem 16.10.2012 um 3:13:38 Uhr geändert wurde:
Der Server empfängt die Anfrage und stellt fest, dass der Client bereits über die neueste Version verfügt. Anstatt den Client zu senden
200 OK
, gefolgt vom Inhalt der Seite, wird Ihnen stattdessen mitgeteilt, dass Ihre zwischengespeicherte Version gut ist:Ihr Browser musste die Verzögerung beim Senden einer Anfrage an den Server erleiden und auf eine Antwort warten, ersparte jedoch das erneute Herunterladen des statischen Inhalts.
Warum Max-Age ? Warum läuft ab ?
Weil Last-Modified scheiße ist.
Nicht allem auf dem Server ist ein Datum zugeordnet. Wenn ich eine Seite im laufenden Betrieb erstelle, ist kein Datum damit verbunden - es ist jetzt . Aber ich bin durchaus bereit, den Benutzer die Homepage 15 Sekunden lang zwischenspeichern zu lassen:
Wenn der Benutzer hämmert F5, erhält er 15 Sekunden lang die zwischengespeicherte Version. Wenn es sich um einen Unternehmens-Proxy handelt, erhalten alle 67198 Benutzer, die dieselbe Seite im selben 15-Sekunden-Fenster aufrufen, denselben Inhalt - alle werden aus dem geschlossenen Cache bereitgestellt. Leistungsgewinn für alle.
Der Vorteil des Hinzufügens
Cache-Control: max-age
besteht darin, dass der Browser nicht einmal eine bedingte Anforderung ausführen muss .Last-Modified
, muss der Browser eine Anforderung ausführenIf-Modified-Since
und auf eine304 Not Modified
Antwort achtenmax-age
, muss der Browser nicht einmal den Netzwerk-Roundtrip erleiden. Der Inhalt kommt direkt aus den CachesDer Unterschied zwischen "Cache-Control: max-age" und "Expires"
Expires
ist ein Legacy-Äquivalent des modernenCache-Control: max-age
Headers (ca. 1998) :Expires
: Sie geben ein Datum an (yuck)max-age
: Sie geben Sekunden an (Güte)Und wenn beide angegeben sind, verwendet der Browser
max-age
:Jede Website, die nach 1998 geschrieben wurde, sollte nicht
Expires
mehr verwendet werden und stattdessen verwendet werdenmax-age
.Was ist ETag?
ETag ähnelt Last-Modified , nur dass es kein Datum sein muss - es muss nur etwas sein .
Wenn ich eine Liste von Produkten aus einer Datenbank ziehe, kann der Server die letzte
rowversion
als ETag und nicht als Datum senden :Mein ETag kann der SHA1-Hash einer statischen Ressource (z. B. Bild, JS, CSS, Schriftart) oder der zwischengespeicherten gerenderten Seite sein (dh das ist, was das Mozilla MDN-Wiki tut; sie haben das endgültige Markup):
Und genau wie bei einer bedingten Anforderung basierend auf Last-Modified :
Ich kann eine bedingte Anforderung basierend auf dem ETag ausführen :
An
ETag
ist überlegen,Last-Modified
weil es für andere Dinge als Dateien oder für Dinge mit Datumsbegriff funktioniert . Es ist einfach soquelle
cache-control
es nicht existiert? Und du hast nur Etag? Muss es nicht immer noch eine "bedingte Anfrage" an den Server stellen? Das Verhalten, das ich sehe, wenn ich offline bin, ist, dass es nur aus dem Cache zurückkehrt. Wenn es jedoch offline ist, kann es diese bedingte Anforderung nicht stellen. Bedeutet das also, dass es unbegrenzt zwischengespeichert wird, wenn Sie offline bleiben? Ich habe diese Frage hier bereits ausführlich gestellt . Kannst du dir das mal ansehen?Aus RFC2616 Abschnitt 14.9.1
quelle
Cache-Control:private
, dass nur angegeben wird, dass gemeinsam genutzte Caches (z. B. Proxy-Caches) die Antwort nicht zwischenspeichern sollten.proxy-revalidate
erfordert, dass Proxys bei jedem Zugriff immer neu validiert werden. Wobei asprivate
verhindert, dass der Proxy zwischengespeichert wird.RFC 2616, Abschnitt 14.9.1 :
Browser könnten diese Informationen verwenden. Natürlich kann der aktuelle "Benutzer" viele Dinge bedeuten: Betriebssystembenutzer, Browserbenutzer (z. B. Chrome-Profile) usw. Es ist nicht angegeben.
Für mich ein konkreteres Beispiel von
Cache-Control: private
ist , dass Proxy - Server (die haben in der Regel viele Benutzer) wird es nicht zwischenspeichern. Es ist für den Endbenutzer und sonst niemanden gedacht.Zu Ihrer Information, der RFC macht deutlich, dass dies keine Sicherheit bietet. Es geht darum, den richtigen Inhalt anzuzeigen und nicht den Inhalt zu sichern.
quelle
Das Feld Expires-Entity-Header gibt das Datum / die Uhrzeit an, nach der die Antwort als veraltet betrachtet wird. Das Feld Cache-Steuerung: maxage gibt den Alterswert (in Sekunden) an, der größer ist als die Antwort, die als veraltet gilt.
Obwohl über dem Header-Feld angegeben, kann der Client entscheiden, ob eine Anforderung an den Server gesendet werden soll. In einigen Fällen sendet der Client eine Anfrage an den Server und der Alterswert der Antwort ist größer als der Maximalwert. Dosis bedeutet dies, dass der Server die Ressource an den Client senden muss? Vielleicht hat sich die Ressource nie geändert.
Um dieses Problem zu beheben, gibt HTTP1.1 den zuletzt geänderten Kopf aus. Der Server gibt dem Client das Datum der letzten Änderung der Antwort. Wenn der Client diese Ressource benötigt, sendet er das Feld If-Modified-Since an den Server. Wenn dieses Datum vor dem Änderungsdatum der Ressource liegt, sendet der Server die Ressource an den Client und gibt 200 Code aus. Andernfalls gibt er 304 Code an den Client zurück. Dies bedeutet, dass der Client die zwischengespeicherte Ressource verwenden kann.
quelle