Was ist Cache-Control: privat?

147

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.

user782220
quelle
Überprüfen Sie dieses Diagramm stackoverflow.com/a/49925190/3748498
pravdomil

Antworten:

73

Um Ihre Frage zu beantworten, warum das Caching funktioniert, obwohl der Webserver die Header nicht enthielt:

  • Läuft ab: [a date]
  • Cache-Kontrolle: maximales Alter =[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):

  • Cache-Kontrolle: privat

Der Server hat jedoch vergessen, Caching-Hinweise anzugeben:

  • Sie haben vergessen, Expires einzuschließen , sodass der Browser die zwischengespeicherte Kopie bis zu diesem Datum verwenden kann
  • Sie haben vergessen, Max-Age einzuschließen , damit der Browser weiß, wie lange das zwischengespeicherte Element gültig ist
  • Sie haben vergessen, E-Tag einzuschließen , damit der Browser eine bedingte Anforderung ausführen kann

Die Antwort enthielt jedoch ein Datum der letzten Änderung :

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

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:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

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:

304 Not Modified

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:

200 OK
Cache-Control: max-age=15

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-agebesteht darin, dass der Browser nicht einmal eine bedingte Anforderung ausführen muss .

  • Wenn Sie nur angegeben haben Last-Modified, muss der Browser eine Anforderung ausführen If-Modified-Sinceund auf eine 304 Not ModifiedAntwort achten
  • Wenn Sie angegeben haben max-age, muss der Browser nicht einmal den Netzwerk-Roundtrip erleiden. Der Inhalt kommt direkt aus den Caches

Der Unterschied zwischen "Cache-Control: max-age" und "Expires"

Expiresist ein Legacy-Äquivalent des modernen Cache-Control: max-ageHeaders (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:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

Jede Website, die nach 1998 geschrieben wurde, sollte nicht Expiresmehr verwendet werden und stattdessen verwendet werden max-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 rowversionals ETag und nicht als Datum senden :

200 OK
ETag: "247986"

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):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Und genau wie bei einer bedingten Anforderung basierend auf Last-Modified :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

Ich kann eine bedingte Anforderung basierend auf dem ETag ausführen :

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

An ETagist überlegen, Last-Modifiedweil es für andere Dinge als Dateien oder für Dinge mit Datumsbegriff funktioniert . Es ist einfach so

Ian Boyd
quelle
1
Genial! Ich habe ein Kopfgeld für diese Antwort gegeben. Was passiert, wenn cache-controles 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?
Honey
167
Cache-Control: private

Gibt an, dass die gesamte oder ein Teil der Antwortnachricht für einen einzelnen Benutzer bestimmt ist und NICHT von einem gemeinsam genutzten Cache wie einem Proxyserver zwischengespeichert werden darf.

Aus RFC2616 Abschnitt 14.9.1

Dan D.
quelle
1
Können
14
Weil es von Ihrem Browser zwischengespeichert wurde. Sie sind der einzelne Benutzer, für den die Antwort bestimmt war.
Dan D.
13
Nein, dies liegt nicht daran Cache-Control:private, dass nur angegeben wird, dass gemeinsam genutzte Caches (z. B. Proxy-Caches) die Antwort nicht zwischenspeichern sollten.
Dan D.
5
@ Trejkaz Nein, es bedeutet wirklich einen einzelnen Benutzer. Ein Benutzer ist ein Konto mit einem eigenen Ausgangsverzeichnis, in dem sich der Cache befindet. Die Profile, die demselben Benutzer gehören, können ihren Cache gemeinsam nutzen. Wie du gefunden hast. Zwei Profile auf demselben Computer, die unterschiedlichen Benutzern gehören, dürfen ihren Cache jedoch nicht gemeinsam nutzen, es sei denn, dieser Cache wird als gemeinsam genutzter Cache behandelt.
Dan D.
2
@didibus proxy-revalidateerfordert, dass Proxys bei jedem Zugriff immer neu validiert werden. Wobei as privateverhindert, dass der Proxy zwischengespeichert wird.
Dan D.
20

RFC 2616, Abschnitt 14.9.1 :

Gibt an, dass die gesamte oder ein Teil der Antwortnachricht für einen einzelnen Benutzer bestimmt ist und NICHT von einem gemeinsam genutzten Cache zwischengespeichert werden darf ... Ein privater (nicht gemeinsam genutzter) Cache kann die Antwort zwischenspeichern.


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: privateist , 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.

Diese Verwendung des Wortes "privat" steuert nur, wo die Antwort zwischengespeichert werden kann, und kann die Privatsphäre des Nachrichteninhalts nicht gewährleisten.

Paul Draper
quelle
5
Ein privater (nicht gemeinsam genutzter) Cache kann die Antwort zwischenspeichern. Dieser Teil ist der Schlüssel. Vielen Dank.
Oliver
0

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.

Lin.Yang
quelle