Что имеет приоритет: заголовок ETag или Last-Modified HTTP? - PullRequest
79 голосов
/ 05 мая 2009

Для двух последующих запросов, какой из следующих двух заголовков имеет больший вес в браузерах, если один из них изменится: ETag или Last-Modified?

Ответы [ 3 ]

88 голосов
/ 13 октября 2009

Согласно разделу 13.3.4 RFC 2616 , клиент HTTP 1.1 ДОЛЖЕН использовать ETag в любых условных запросах кеша, и если присутствуют оба ETag и Last Modified, он ДОЛЖЕН использовать оба. Заголовок ETag считается сильным валидатором (см. Раздел 13.3.3), если только сервер явно не объявил его слабым, в то время как заголовок Last Modified считается слабым, если между ним и заголовком Date не существует как минимум минутной разницы. Обратите внимание, однако, что Сервер также не обязан отправлять (но ДОЛЖЕН, если может).

Обратите внимание, что Клиент не проверяет заголовки, чтобы увидеть, изменились ли они; он просто слепо использует их в следующем условном запросе; Сервер должен оценить, отправлять ли запрошенный контент или ответ 304 Not Modified. Если Сервер отправляет только один, то Клиент будет использовать его один (хотя для запроса Range полезны только сильные валидаторы). Разумеется, на усмотрение промежуточных кэшей (если только им не было запрещено кэширование с помощью директив управления кэшем) и серверам указывается, как они будут действовать на заголовки; RFC заявляет, что они НЕ ДОЛЖНЫ возвращать 304 Not Modified, если валидаторы несовместимы, но поскольку значения заголовков генерируются сервером, у него есть немного свободы.

На практике я заметил, что Chrome, FireFox и IE 7+ отправляют оба заголовка, если они доступны. Я также проверил поведение при отправке модифицированных заголовков, что я уже подозревал из информации в RFC. Четыре проверенных клиента отправляли условные запросы только в том случае, если страницы обновлялись или это был первый раз, когда страница запрашивалась текущим процессом.

20 голосов
/ 05 мая 2009

Разве это не похоже на выражение "ИЛИ"? В псевдокоде:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
8 голосов
/ 14 ноября 2014

=! правильный оператор сравнения. Клиент должен сохранять литеральную строку, полученную от сервера, поскольку преобразования могут создавать небольшие различия. Вы не можете предполагать, что «чем новее, тем лучше».

Почему? Рассмотрим случай, когда оператор сервера возвращает неверную версию ресурса. Вернутая версия - более старая, но правильная.

Клиент должен использовать версию, предлагаемую в данный момент сервером; он может использовать кэшированную версию, только если она одинакова. Таким образом, сервер должен проверять равенство, а не «новее».

...