Що має перевагу: заголовок ETag або остання зміна HTTP?


83

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

Відповіді:


90

Згідно з RFC 2616, розділ 13.3.4, клієнт HTTP 1.1 ПОВИНЕН використовувати ETag у будь-яких умовних запитах кешу, і якщо присутні як ETag, так і Last Modified, він СЛІД використовувати обидва. Заголовок ETag вважається сильним валідатором (див. Розділ 13.3.3), якщо сервер явно не оголосив його слабким, тоді як Заголовок останньої модифікації вважається слабким, якщо між ним та заголовком Дати не існує щонайменше хвилинної різниці. Однак зверніть увагу, що Сервер також не повинен надсилати (але СЛІД, якщо це можливо).

Зверніть увагу, що Клієнт не перевіряє заголовки, чи не змінилися вони; він просто наосліп використовує їх у наступному умовному запиті; Сервер повинен вирішити, чи надсилати запитуваний вміст, чи відповідь 304 Not Modified. Якщо Сервер надсилає лише один, то Клієнт буде використовувати його поодинці (хоча для запиту Range корисні лише сильні валідатори). Звичайно, це також на розсуд проміжних кеш-пам’яті (якщо їм не було заблоковано кешування за допомогою директив кешування) та Серверу щодо того, як вони діятимуть на заголовки; RFC стверджує, що вони НЕ ПОВИННІ повертати 304 Not Modified, якщо валідатори несумісні, але оскільки значення заголовків генеруються сервером, він має досить велику свободу дій.

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


1
Чудова відповідь, Томасе. Дякуємо за надання офіційних специфікацій та обговорення поточних реалізацій браузера.
dthrasher

1
Посилаючись на розділ 14.26, сервер НЕ ПОВИНЕН виконувати запитуваний метод, якщо це не потрібно, оскільки дата модифікації ресурсу не відповідає даній, вказаній у полі заголовка If-Modified-Since у запиті. Схоже, що If-Modified-Since має пріоритет.
Вікарій

20

Хіба це не більше як вираз "АБО". У псевдокоді:

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

4
Я думаю, що останню змінену мітку часу слід порівнювати інакше, як у: if ETagFromServer! = ETagOnClient || LastModifiedFromServer> LastModifiedOnClient
RoyM

Це твердження AND, оскільки ETag може бути слабким, і в цьому випадку у вас може бути семантично еквівалентна сутність, а потім ви повернетесь до останньо зміненого заголовка. Розглянемо ситуацію, коли зображення можна перекодувати, і ми хочемо сказати, що оригінал та перекодування однакові, незважаючи на те, що вони не є ідентичними по байтах. У цьому випадку ми хочемо використати останньо модифіковані як запасний
варіант,

8

=! є правильним оператором порівняння. Клієнт повинен зберігати буквальний рядок, отриманий від сервера, оскільки перетворення можуть створювати невеликі відмінності. Ви не можете припустити, що "новіше - краще".

Чому? Розглянемо випадок, коли оператор сервера повертає неправильну версію ресурсу. Скасована версія СТАРІША - але правильна.

Клієнт повинен використовувати версію, пропоновану на даний момент сервером; він може використовувати кешовану версію, лише якщо вона однакова. Таким чином, сервер повинен перевіряти рівність, а не "новішу".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.