ETag против заголовка истекает

359

Я огляделся, но не смог понять, должен ли я использовать ETag и Expires Header или один или другой.

То, что я пытаюсь сделать, это убедиться, что мои флеш-файлы (и другие изображения и что не только обновляются, когда есть изменения в этих файлах).

Я не хочу делать ничего особенного, например, изменять имя файла или помещать странные символы в конец URL, чтобы он не кэшировался.

Кроме того, есть ли что-то, что мне нужно сделать программно на моем конце в моих сценариях PHP, чтобы поддержать это, или это все Apache?

GeoffreyF67
источник
1
developer.mozilla.org/en-US/docs/Web/HTTP/Caching (хорошо в целом)
Кристоф Русси

Ответы:

677

Они немного отличаются - у ETag нет никакой информации, которую клиент может использовать, чтобы определить, следует ли делать запрос на этот файл снова в будущем. Если ETag - это все, что у него есть, он всегда должен будет сделать запрос. Однако, когда сервер считывает ETag из запроса клиента, сервер может затем определить, следует ли отправить файл (HTTP 200) или сказать клиенту просто использовать их локальную копию (HTTP 304). ETag - это просто контрольная сумма для файла, который семантически изменяется при изменении содержимого файла.

Заголовок Expires используется клиентом (и прокси-серверами / кэшами), чтобы определить, нужно ли ему вообще отправлять запрос серверу. Чем ближе вы находитесь к дате истечения срока действия, тем больше вероятность того, что клиент (или прокси-сервер) сделает HTTP-запрос для этого файла с сервера.

Поэтому на самом деле вы хотите использовать ОБА заголовки - установите для заголовка Expires разумное значение, основанное на частоте изменения содержимого. Затем настройте отправку ETag так, чтобы, когда клиенты отправляли запрос на сервер, он мог легче определить, следует ли отправлять файл обратно.

Последнее замечание об ETag - если вы используете установку сервера с балансировкой нагрузки на нескольких машинах, работающих под управлением Apache, вы, вероятно, захотите отключить генерацию ETag. Это связано с тем, что inode используются как часть алгоритма хеширования ETag, который будет отличаться для разных серверов. Вы можете настроить Apache так, чтобы он не использовал inode в качестве части вычисления, но затем вы должны убедиться, что временные метки в файлах совпадают, чтобы гарантировать, что один и тот же ETag генерируется для всех серверов.

Марк Новаковский
источник
12
Вы также должны проверить, следует ли использовать Cache-Control вместо Expires. Насколько я понимаю, Cache-Control был введен после Expires и дает вам больше контроля. См. Stackoverflow.com/questions/5799906/…
Луис Перес
6
При использовании заголовка Expires рекомендуется менять имя файла при каждом изменении ресурса, поскольку клиент не будет запрашивать файл снова, пока он не устарел. Особенно, если вы используете дальние будущие значения в качестве даты истечения срока действия.
шнаттерер
8
Допустим, мы будем использовать оба. Что происходит, когда истекает время истечения, но файл не изменяется (Etag такой же)? Сервер вернет 304, и файл будет обслуживаться из кэша браузера. Мой вопрос, будет ли восстановлено время истечения в этот момент?
user345602
2
Будьте внимательны при установке ETAG и заголовка Expires на ненулевое значение. Это может привести к гоночным условиям. См. Jakearchibald.com/2016/caching-best-practices
Уэстон,
2
Можно ли сказать серверам вообще не использовать inode или метки времени? Кроме того, зачем они нужны для ETag, если он используется только для представления контента?
Сезар Кастро
108

Заголовки Etag и Last- updated являются валидаторами .

Они помогают браузеру и / или кешу (обратному прокси) понять, изменился ли файл / страница, даже если он сохраняет то же имя.

Expires и Cache-control дают информацию об обновлении .

Это означает, что они информируют браузер и обратные промежуточные прокси, до какого времени или в течение какого времени они могут хранить страницу / файл в своем кэше.

Поэтому обычно возникает вопрос: какой валидатор использовать, etag или последний измененный, а какой обновлять заголовок информации для использования, срок действия или контроль кэша.

Джон
источник
31

Expiresи Cache-Controlявляются "сильными заголовками кэширования"

Last-Modifiedи ETagявляются "слабыми заголовками кэширования"

Сначала проверьте браузер, Expires/Cache-Controlчтобы определить, следует ли делать запрос на сервер

Если нужно сделать запрос, он отправит Last-Modified/ETagв HTTP-запрос. Если Etagзначение документа совпадает с этим, сервер отправит код 304 вместо 200 без содержимого. Браузер загрузит содержимое из своего кэша.

hienbt88
источник
1
Считаете ли вы, что какой-либо документ поддерживает "сильное и слабое" поведение кэширования? Я не смог найти его, и мой клиентский браузер теперь устанавливает приоритет над последними изменениями, а не истекает, что я не понимаю, почему.
GMsoF
1
@GMsoF Вы можете взглянуть на это: tools.ietf.org/html/rfc7232#section-2.1
Medeiros
Итак, если я хочу убедиться, что мои изменения будут немедленно переданы клиенту, но все же выиграют от некоторого кэширования, я могу использовать только Last-Modified и ETag, верно?
Себастьян Лорбер
Это самый лаконичный и самый ясный ответ для меня! Спасибо.
aderchox
18

По умолчанию Apache сгенерирует Etag на основе номера инода файла, даты последнего изменения и размера, что должно быть идеально для выполнения того, что вы хотите. Я думаю, что он также будет генерировать по умолчанию заголовок Last-Modified, основанный на времени последнего изменения файла на диске, что также прекрасно подходит для того, что вы хотите.

Возможно, вам также следует, чтобы Apache отправлял заголовок Expires, датированный одним годом в будущем (согласно http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 ), чтобы браузеры знали, что содержимое кэшируется. Посмотрите на mod_expires, чтобы настроить это.

Дэвид З
источник
Таким образом, ETag будет иметь последнее изменение, и заголовок expires сообщит ему, что я хочу, чтобы он кешировал его, и когда я загружаю и перезаписываю свой файл, он просто снова загружается в кэш пользователя, иначе будет сгенерирован 304, верно?
GeoffreyF67
Этаг сложным образом зависит от даты последнего изменения; но когда вы измените файл, Etag изменится. Тогда Etag, отправленный браузером (для его кэшированной версии файла), не будет соответствовать Etag файла на сервере, и Apache отправит файл, а не ответ 304.
Дэвид З
6
Разве заголовок истечения одного года не скажет клиенту даже не проверять новую версию в течение одного года?
Джон Башир
@Джон: да, наверное, я думал о статическом контенте, который никогда не меняется, когда я это пишу.
Дэвид З
2
@Джон Бачир: это должно быть поведение expecetd, но браузер, похоже, все равно ударит по серверу, по крайней мере, для запроса новой версии. Я открыл еще один вопрос об этой проблеме: stackoverflow.com/questions/10048740/…
Марко Демайо
13

Еще одно резюме:

Вы должны использовать оба. ETag - это информация «на стороне сервера». Срок действия - кэширование на стороне клиента.

  • Используйте ETag, кроме случаев, когда у вас есть сервер с балансировкой нагрузки. Они безопасны и сообщат клиентам, что они должны получать новые версии файлов вашего сервера каждый раз, когда вы что-то меняете на своей стороне.

  • Срок действия истекает с осторожностью, так как если вы устанавливаете дату истечения срока давности в будущем, но хотите немедленно изменить один из файлов (например, файл JS), некоторые пользователи могут не получить измененную версию в течение длительного времени!

Бенджамин Пиетт
источник
2
В случае такой ситуации Expires вам, в основном, нужно переименовать js и изменить его в своем HTML, и надеяться, что вы также не установили истечение срока действия HTML-файла на 1 год.
EralpB
1

Еще одна вещь, которую я хотел бы отметить, что некоторые из ответов, возможно, пропустили, является недостатком наличия обоих ETagsи Expires/Cache-controlв ваших заголовках.

В зависимости от ваших потребностей, он может просто добавить дополнительные байты в заголовки, что может увеличить количество пакетов, что означает дополнительные издержки TCP. Опять же, вы должны увидеть, необходимы ли накладные расходы на наличие обеих вещей в ваших заголовках, или это просто добавит дополнительный вес вашим запросам, что снизит производительность.

Вы можете прочитать больше об этом в этом превосходном сообщении в блоге Кайла Симпсона: http://calendar.perfplanet.com/2010/bloated-request-response-headers/

aneagoie
источник
1

На мой взгляд, с помощью заголовка Expire сервер может сообщить клиенту, когда мои данные будут устаревшими, в то время как с помощью Etag сервер будет проверять значение etag для каждого запроса клиента.

Солнечный
источник
0

ETag используется для определения, должен ли ресурс использовать копию. Заголовок Expires, такой как Cache-Control, сообщает клиенту, что до десятилетий кэша клиент должен получить локальный ресурс.

На современных сайтах часто предлагают файл с именем hash, например app.98a3cf23.js , так что рекомендуется использовать Expires Header. Помимо этого, это также снижает стоимость сети.

Надеюсь, поможет ;)

Джек Чен
источник