Header, um 304 / If-modified-since / HEAD-Anforderungen zu verhindern

31

Welche Header sollte ich senden, um alle Anforderungen an den Server zu stoppen, nachdem der Inhalt zwischengespeichert wurde?

Wir haben einen Server mit sehr hoher Latenz (Sigh, VMWare), sodass das Senden einer HEADAnfrage an den Server + 40ms dauert.

Derzeit werden die Header gesendet / empfangen.

Erste Anfrage

Client sendet;

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

Server antwortet;

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

Es wird also ein Cache-Controlund ein ExpiresHeader gesendet, der auf 365 Tage in der Zukunft festgelegt ist. Leider fordert es bei der zweiten Aktualisierung das Objekt erneut mit einem If-Modified-SinceHeader an.

Zweite Anfrage

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

Antwort;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

Leider können wir aufgrund alberner veralteter Proxy-Software Keep-Alivekeine anderen Server / Proxys vor die Anwendung stellen. Wir können auch die Leistung des Servers nicht verbessern und die Netzwerklatenz nicht reduzieren. Ich habe versucht herauszufinden, welche Header wir senden können, um die 301-Anfragen loszuwerden. Ich habe versucht, ETags zu verwenden, aber das macht keinen Unterschied, es sendet immer noch einen If-modified-sinceHeader. Ich habe auch versucht, den Last-ModifiedHeader zu entfernen, aber dies führt nur zu einer Standard-GET-Anforderung ohne Zwischenspeicherung (Protokolle überprüft, Server empfängt weiterhin Anforderungen).

Clients sind eine Mischung aus Firefox (meistens), IE 7, 8 und (einigen) 9, Chrome und Safari, aber dieses Verhalten scheint in allen getesteten Browsern aufzutreten.

TL; DR;

Schreckliches Netzwerk, welche Header sollte ich senden, um Clients anzuweisen, niemalsIf-modified-since Anfragen an den Server zu senden , um ihren Cache zu validieren und den Inhalt zwischenzuspeichern, bis der ExpiresHeader erfüllt ist?

Ich vermisse wahrscheinlich etwas Offensichtliches, aber alles, was ich versuche, scheint zu den gleichen Ergebnissen zu führen.

Wir haben einen NGINX-Server vor unserem Anwendungsserver, sodass ich nach Belieben Header hinzufügen / entfernen kann. Unser Proxy unterstützt Keep-Alive nicht und es gibt keine Möglichkeit, die Netzwerkleistung zu verbessern. Aufgrund des schlechten Softwaredesigns lädt die Web-App bei jedem Seitenaufruf +100 Ressourcen (Ja, Unternehmenssoftware saugt) mit einer Latenz von ~ 40-50 ms pro Objekt.

Verschmieren
quelle
1
Hmm, das ist komisch. Das Senden der Header "Expires" und "Max Age" sollte weitere Anforderungen des Bildes verhindern. Edit: übrigens, wie sieht es mit dem Senden eines JPG aus text/plain?
DisgruntledGoat
1
@DisgruntledGoat Ahh, Sie haben angenommen, eine .jpg-Datei ist eigentlich ein Bild und kein Textdokument. Willkommen in meiner Welt =) (Tatsächlich ist es eine Textdatei, die 'Hallo Welt' für meine Tests enthält. Die Software benennt alle Dateien nacheinander um, unabhängig vom Typ. Cool huh?)
Smudge
Womit haben Sie die HTTP-Anforderungsheader festgelegt?
Barlop

Antworten:

25

Sie können nicht wirklich steuern, welche Header Benutzeragenten an Sie senden möchten. Befindet sich die betreffende Datei im Cache des Browsers und muss nach einer neuen Version gesucht werden, wird dies der Fall sein. Laut diesem Artikel , das sind die Situationen Browser If-Modified-Since verwendet wird darum ersuchen:

  • 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

Wenn Sie also die Seite neu laden, um Ihr Caching zu testen, funktioniert dies nicht, da der Browser die Bilder erneut anfordert. Klicken Sie auf einen Link und dann auf einen anderen Link, um zur ersten Seite zurückzukehren. Wenn Ihre Benutzer regelmäßig Seiten neu laden, müssen Sie möglicherweise Ihre Site- / App-Struktur überdenken, um dies zu verhindern.

Eine Sache, die helfen kann, ist das Hinzufügen von "public" zum Cache-Control-Header, dh Cache-Control: public, max-age=31536000. Ich habe auch kürzlich erfahren, dass ein Ablaufdatum von mehr als einem Jahr ungültig ist. Da Ihr Ablaufdatum genau ein Jahr beträgt, können Sie durch Verringern dieses Datums um einige Tage oder Wochen sicherstellen, dass die Datei im Browser-Cache bleibt und nicht verworfen wird.

Verärgerte Ziege
quelle
Interessant, ich werde das Ablaufdatum auf 60 Tage senken und die öffentliche Flagge hinzufügen und sehen, was passiert. Dies schien eher auf Link-Klicks als auf F5-Klicks zu beruhen (laut Firebug und den Server-Protokollen)
Smudge
Technisch gesehen besagt die HTTP / 1.1-Spezifikation nur, dass "Server KEINE Verfallsdaten mehr als ein Jahr in der Zukunft senden SOLLTEN" (vermutlich, weil dies eine lächerlich lange Zeit vor dem Verfall ist) und dass "ungefähr ein Jahr" in der Zukunft das angemessene Verfallsdatum ist Zeit zum Senden von Inhalten, deren Ablauf niemals erwartet wird.
Ilmari Karonen
1
Nach einigem Herumspielen bin ich zu dem Schluss gekommen, dass der 365d-Verfall keine Auswirkungen auf unsere Kunden hat. Ich habe ihn jedoch aus Sicherheitsgründen fallen lassen. Offenbar Cache-Control: public,...war dies der Schlüssel zu dieser speziellen Situation.
Fleck
Meinst du, der "öffentliche" Header hat die unnötigen Roundtrips behoben? Ich habe es versucht, aber ohne Erfolg ...
Phtrivier
2
Falls sich aus meiner Antwort nichts ergibt, werden die Dateien beim erneuten Laden der Seite in Ihrem Browser erneut abgefragt . Klicken Sie einfach auf Links, um Seiten zu öffnen, und der Browser verwendet seinen Cache.
DisgruntledGoat
3

Ich hatte das gleiche Problem, und die Anfragen treffen definitiv den Server, damit er mit dem 304Status antwortet. Ich sende den 304 über ein C # und sicher trifft er den Server.

Ich hatte nur Cache-Control: privategesetzt. Nein max-ageund nein ExpiresEs funktionierte wie erwartet; Schlagen Sie den Server mit dem If-Modified-SinceWert an, bei dem ich den Wert im Vergleich zu dem erwarteten Wert teste und einen 304leeren Antworttext erhalte - andernfalls ist 200der Antworttext voll.

Das Setzen des ExpiresHeaders führte zu den gewünschten Ergebnissen. 200 - (from cache)Auf dem Client wurden keine HTTP-Anforderungen auf den Server gesendet.

Aber ich habe festgestellt, dass das Setzen von BEIDE max-age= & Expiresdazu führen kann, dass Browser keine If-Modified-SinceHeader senden UND überhaupt nicht zwischenspeichern, wenn die Werte nicht übereinstimmen .

Beachten Sie, dass bei Caching-Problemen die verschiedenen Header in Kombination verwendet werden.

Andrew Scott
quelle
1

Ein wenig off-topic, aber vielleicht hilfreich. Eine weitere Verbesserung für Ihre Anforderungen von zwischengespeicherten Inhalten besteht darin, in sessionStorage zwischenzuspeichern, sodass Sie den Server nicht auffordern müssen, den Cache zu validieren und eine 304 zu erhalten. Suchen Sie beispielsweise nach Google, öffnen Sie die Konsole und schreiben Sie sessionStorage. Sie werden sehen, dass sie CSS oder DOM mit dem sessionStorage zwischenspeichern. ofc, das kann man in alten IE-Browsern nicht verwenden.

Pablo Estornut
quelle
0

Durchsuchen Sie Ihren Quellcode und stellen Sie sicher, dass es keine META REFRESH gibt, die auf eine andere Seite wechseln könnten. Verwenden Sie stattdessen so etwas wie sendRedirect. In meinem Setup erzeugt META REFRESH 304s im IE, aber nicht Chrome. sendRedirect erzeugt dies in keinem Browser.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

vs

<% response.sendRedirect("nextpage") %>
Richard Sandoz
quelle