Что имеет приоритет: HTTP-заголовок ETag или Last-Modified?

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


person user101442    schedule 05.05.2009    source источник


Ответы (3)


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

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

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

person Thomas S. Trias    schedule 13.10.2009
comment
Отличный ответ, Томас. Благодарим за предоставление официальной спецификации и обсуждение текущих реализаций браузеров. - person dthrasher; 21.12.2009
comment
Цитируя раздел 14.26, сервер НЕ ДОЛЖЕН выполнять запрошенный метод, если это не требуется, потому что дата модификации ресурса не соответствует дате, указанной в поле заголовка If-Modified-Since в запросе. Похоже, например, If-Modified-Since имеет приоритет. - person Vicary; 24.01.2013

Разве это не больше похоже на выражение «ИЛИ». В псевдокоде:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
person Gideon    schedule 05.05.2009
comment
Я думаю, что последнюю измененную метку времени следует сравнивать по-другому, например: if ETagFromServer! = ETagOnClient || LastModifiedFromServer ›LastModifiedOnClient - person RoyM; 31.08.2014
comment
Это оператор AND, потому что ETag может быть слабым, и в этом случае у вас может быть семантически эквивалентный объект, а затем вы вернетесь к последнему измененному заголовку. Рассмотрим ситуацию, когда изображение можно перекодировать, и мы хотим сказать, что исходное и перекодированное одинаковы, несмотря на то, что они не идентичны по байтам. В этом случае мы хотим использовать последнее изменение в качестве запасного варианта, и поэтому они ОБЕИХ должны быть согласованными. - person ParoX; 24.03.2016

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

Почему? Рассмотрим случай, когда оператор сервера отменяет плохую версию ресурса. Восстановленная версия СТАРШАЯ, но верная.

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

person AccuracyInReponses    schedule 14.11.2014