Warum sendet Apache 200 OK, während die zuletzt geänderten Übereinstimmungen übereinstimmen, wenn-geändert-seit?

10

Ich versuche, ein grundlegendes Verhalten in Bezug auf meine Caching-Strategie zu haben: Dateien sollten jedes Mal zwischengespeichert und mit dem Server erneut validiert werden. Also möchte ich, dass Apache einen 304 zurückschickt.

Hier ist der Dialog, der bei jeder Browseraktualisierung angezeigt wird:

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(Dies ist von Chrome Devtools, wobei Cache deaktivieren deaktiviert ist.)

Sie können sehen, dass die Antwort den Header "Cache-Steuerung: Kein Cache" enthält und dass der Header "Wenn geändert seit" mit dem Header "Zuletzt geändert" übereinstimmt. Das ETag passt auch.

Sollte Apache in diesem Fall nicht eine 304 senden?

BEARBEITEN

Deaktivieren von ETags in Apache mit

 Header  unset ETag

macht das Caching-Verhalten vorhersehbarer ...

zrz
quelle
Ich denke, Cache-Control:max-age=0den Cache deaktiviert, so dass Sie die Cache-Control:No-cacheAntwort sehen.
ThoriumBR
Ich habe Cache-Control: No-Cache in meiner Apache-Konfiguration explizit festgelegt, da ich unter w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 verstehe, dass dies für jede Anforderung eine erneute Validierung verursacht. Bedeutet eine erneute Validierung das erneute Senden der Datei? Ich würde sagen, es sollte If-modifiziert-seit verwenden, um festzustellen, ob es eine 200 oder eine 304 ist.
zrz

Antworten:

8

Dies scheint ein alter Fehler zu sein , der erklärt, warum dies Header unset ETageinen Unterschied macht.

Apache 2.4.0+ hängt den Namen der Komprimierungsmethode automatisch an das ETag an (wie in Ihren Headern angegeben) und verhindert eine 304-Antwort.

Neueste Versionen von mod_deflate unterstützen ein DeflateAlterETag , mit dem dieses Verhalten gesteuert werden kann:

DeflateAlterETag NoChange
Mathias R. Jessen
quelle
3
Dies ist korrekt, aber Apache 2.4 enthält diese Option nicht, nur Apache 2.5. Ich persönlich finde ETags jedoch nicht so nützlich, da Apache sie eher auf dem Datum der letzten Änderung als auf dem Inhalt der Datei basiert. Das Deaktivieren von ETags fällt also auf den If-Modified-Since-Header zurück, der ohnehin auf dem Datum der letzten Änderung basiert. Sie können das ETag in Apache so ändern, dass es auf der Größe, der letzten Änderung und / oder dem Inode basiert - wobei Größe und letzte Änderung die Standardeinstellung sind. Bis sie jedoch eine Option zum Berechnen eines ETag basierend auf der Prüfsumme des Dateiinhalts hinzufügen, Es ist meiner Meinung nach von begrenztem Nutzen. Also schalte ich sie aus.
Barry Pollard
1
@BazzaDP Das macht Sinn. 2.5 hat auch die DeflateAlterETag RemoveOption, genau das
Mathias R. Jessen
0

Dieser fällt in der Anfrage als etwas seltsam auf:

Cache-Control:max-age=0

Wahrscheinlich wichtiger ist jedoch, dass der zurückgegebene Inhalt HTML ist. Wird es dynamisch generiert? Apache kann eine 304-Antwort senden, aber wenn Sie keinen statischen Inhalt bereitstellen, ist es nicht Apaches Aufgabe, diesen Aufruf zu tätigen, und es hängt von Ihrer Anwendungslogik ab. ZB haben die meisten PHP-Anwendungen eine begrenzte Unterstützung für solche Dinge.

Ein Front-End-Cache kann hilfreich sein, da die Caching-App die Änderungszeit, das Etag usw. überprüfen kann, jedoch nur, wenn sowohl die Anwendung als auch die Anforderungsheader cachefreundlich sind. Beispielsweise muss die Anwendung geeignete Header festlegen, um anzuzeigen, dass der Inhalt zwischengespeichert werden kann, und Dinge wie der Cache-Steuerungsheader in Ihrer Anforderung negieren den Cache. Ihre Header sehen nicht cachefreundlich aus.

mc0e
quelle
Die angeforderte Datei ist eine statische HTML-Datei, für die Apache die richtige Änderungszeit erhält. (Letzte Änderung: Di, 14. Oktober 2014, 15:10:37 GMT). Der Header max-age = 0 befindet sich in der von Chrome gesendeten Anfrage, wenn ich die URL eingebe und die Eingabetaste drücke. Liegt es an früheren Antworten?
zrz
Ich habe gelesen, dass Chrome automatisch Cache-Control hinzufügt: max-age = 0 zur Anforderung (außer beim ersten Laden von Chrome, geben Sie die URL ein und drücken Sie die Eingabetaste). Dies scheint jedoch keine Auswirkungen auf andere Server zu haben (CDNs senden 304 auch bei maximalem Alter = 0 in der Anforderung).
zrz
@zrz: Das Einschränken des Zwischen-Caching ist beim Debuggen sehr nützlich, würde aber ansonsten die Leistung beeinträchtigen. Überprüfen Sie den Kontext dessen, was Sie über die Funktionsweise von Chrom lesen. In Bezug auf das, was Apache tut, ist es ziemlich konfigurierbar. Die Cache-Steuerung ist eine Anweisung für Zwischen-Caches, nicht für den Ursprungsserver. Apache kann jedoch als Zwischencache fungieren und für alle möglichen Aufgaben konfiguriert werden. Ich denke, wenn Sie Ihre Anti-Caching-Anweisungen herausnehmen, erhalten Sie ein Verhalten, das eher dem entspricht, was Sie von einem Ursprungsserver erwarten.
mc0e
0

Wenn Sie Apache mit konfiguriert haben Cache-Control:No-cache, sendet Apache niemals eine HTTP 304 Not modifiedan den Client.

Wenn Sie einige Anforderungen erneut validieren möchten, setzen Sie eine Cache-Control:No-cachenur auf die Seiten, auf denen Sie diese benötigen. Sie müssen nicht alle Ressourcen erneut validieren und verschwenden dadurch Bandbreite.

ThoriumBR
quelle
Ich scheine durch den Begriff "revalidate" verwirrt zu sein. Für mich bedeutet es zu überprüfen, ob es ein 304 ist. Bin ich falsch?
zrz
Sie liegen falsch. Revalidate besteht darin, alle Daten erneut an den Client zu senden und ihn zu zwingen, alles erneut zu lesen, auch wenn es bereits dieselben Informationen enthält. Grundsätzlich deaktivieren Sie den Cache auf jedem Client.
ThoriumBR
Das erklärt einiges. Das Letzte, was ich vor diesem Hintergrund erklären muss, ist, dass Apache 304 für einige Ressourcen sendet (z. B. PNG), während Cache-Control in der Antwort immer noch keinen No-Cache und in der Anfrage auf max-age = 0 gesetzt hat. Irgendeine Ahnung ?
zrz
@ThoriumBR Wenn ich Sie richtig interpretiert habe, sind Ihre beiden Antworten hier falsch. no-cache (im Gegensatz zu no-store) bedeutet nicht "nicht zwischenspeichern" und kann zu einem 304 führen, wenn sich der Inhalt nicht geändert hat. Das OP hat dies zwar erwartet, aber aufgrund des etag-Problems nicht erhalten. must-revalidate bezieht sich darauf, wie veraltete Inhalte behandelt werden, und sendet nicht immer "alle Daten erneut".
Nick