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

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

Ответ 1

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

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

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

Ответ 2

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

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache

Ответ 3

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

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

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