Co ma pierwszeństwo: nagłówek HTTP ETag lub Last-Modified?

83

W przypadku dwóch kolejnych żądań, który z poniższych nagłówków ma większą wagę w przeglądarkach, powinien zmienić jeden z nich: ETag czy Last-Modified?

user101442
źródło

Odpowiedzi:

91

Zgodnie z sekcją 13.3.4 RFC 2616 , klient HTTP 1.1 MUSI używać ETag we wszystkich żądaniach warunkowych dla pamięci podręcznej, a jeśli obecne są zarówno ETag, jak i Last Modified, POWINIEN używać obu. Nagłówek ETag jest uważany za silny walidator (patrz sekcja 13.3.3), chyba że serwer wyraźnie zadeklarował, że jest słaby, podczas gdy nagłówek Last Modified jest uważany za słaby, chyba że istnieje co najmniej minutowa różnica między nim a nagłówkiem Date. Należy jednak pamiętać, że serwer też nie musi wysyłać (ale POWINIEN, jeśli może).

Zauważ, że Klient nie sprawdza nagłówków, aby zobaczyć, czy się zmieniły; po prostu ślepo używa ich w następnym żądaniu warunkowym; do serwera należy ocena, czy wysłać żądaną zawartość, czy też 304 nie zmodyfikowano odpowiedzi. Jeśli serwer wyśle ​​tylko jeden, klient użyje tego samego (chociaż tylko silne walidatory są przydatne w przypadku żądania Range). Oczywiście, zależy to również od pośrednich pamięci podręcznych (chyba, że ​​zostały one zablokowane przez dyrektywy kontroli pamięci podręcznej) i serwera, jak będą działać na nagłówkach; RFC stwierdza, że ​​NIE MOGĄ zwracać 304 Not Modified, jeśli walidatory są niespójne, ale ponieważ wartości nagłówków są generowane przez serwer, ma to spore pole do popisu.

W praktyce zauważyłem, że Chrome, FireFox i IE 7+ wysyłają oba nagłówki, jeśli są dostępne. Przetestowałem również zachowanie podczas wysyłania zmodyfikowanych nagłówków, co już podejrzewałem na podstawie informacji w RFC. Czterech klientów, których testowałem, wysyłało żądania warunkowe tylko wtedy, gdy strona (y) zostały odświeżone lub jeśli był to pierwszy raz, gdy strona została zażądana przez bieżący proces.

Thomas S. Trias
źródło
1
Świetna odpowiedź, Thomas. Dziękujemy za dostarczenie oficjalnej specyfikacji i omówienie aktualnych implementacji przeglądarek.
dthrasher
1
Cytując z sekcji 14.26, serwer NIE MOŻE wykonać żądanej metody, chyba że jest to wymagane, ponieważ data modyfikacji zasobu nie zgadza się z datą podaną w polu nagłówka If-Modified-Since w żądaniu. Wygląda na to, że pierwszeństwo ma If-Modified-Since.
Vicary
20

Czy to nie bardziej przypomina wyrażenie „LUB”. W pseudokodzie:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
Gideon
źródło
4
Myślę, że ostatnio zmodyfikowany znacznik czasu powinien być porównany inaczej, na przykład: if ETagFromServer! = ETagOnClient || LastModifiedFromServer> LastModifiedOnClient
RoyM
Jest to instrukcja AND, ponieważ ETag może być słaby, w którym to przypadku możesz mieć semantycznie równoważną encję, a następnie powrócić do ostatnio zmodyfikowanego nagłówka. Rozważmy sytuację, w której obraz mógłby zostać ponownie zakodowany i chcemy powiedzieć, że oryginał i ponowne kodowanie są takie same, mimo że nie są identyczne w bajtach. W tym przypadku chcemy użyć ostatniej modyfikacji jako rozwiązania zastępczego i dlatego OBIE muszą być spójne
ParoX
8

=! jest poprawnym operatorem porównania. Klient musi zachować ciąg literału otrzymany z serwera, ponieważ konwersje mogą powodować niewielkie różnice. Nie można zakładać, że „nowsze jest lepsze”.

Czemu? Rozważmy przypadek, w którym operator serwera przywraca złą wersję zasobu. Przywrócona wersja jest STARSZA - ale poprawna.

Klient musi korzystać z wersji aktualnie oferowanej przez serwer; może używać wersji buforowanej tylko wtedy, gdy jest taka sama. Dlatego serwer musi sprawdzać równość, a nie „nowszy”.

AccuracyInReponses
źródło