HTTP. Часть 13. Кэширование содержимого HTTP на стороне клиента

Когда информация передается клиенту через Internet, то клиент — обычно, браузер — может локально кэшировать ее.

Локальный кэш снижает требования к каналу связи и повышает производительность. С учетом того, что большая часть содержимого Internet, если не все, изменяется относительно редко в контексте отдельного пользовательского сеанса, кэширование становится незаменимым средством повышения производительности.

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

К решению упомянутой проблемы существуют два стандартных подхода, включающих использование HTTP-заголовков. Первый метод проверяет наиболее свежие модификации по временной метке документа, в то время как второй метод проверяет изменения в дескрипторе сущности (Entity tag — E-Tag), ассоциированном с запрашиваемым ресурсом.

Кэширование также может управляться или модифицироваться с помощью HTTP-заголовков Cache-Control и Pragma. Обычно они применяются в ситуациях, когда вы хотите указать, что определенный документ не должен кэшироваться на клиенте.

Заголовок Pragma используется, начиная с версии HTTP 1.0, и сопровождается значением No-cache для выключения кэширования, как показано ниже:

Pragma: No-cache

Если вы используете HTTP 1.1, то захотите применять заголовок Cache-Control, который заменил Pragma.
Ниже показан эквивалент предыдущего выражения

Pragma: Cache-Control: No-cache

Классическое кэширование HTTP 1.0 управлялось с применением заголовка If-Modified-Since в запросе GET. При таком подходе клиент сообщал серверу, что он должен присылать данные для указанного URL, только если они были модифицированы после заданного момента времени, переданного в заголовке. Если документ не модифицировался, посылался код состояния 304 (Not Modified).

Кроме заголовка If-Modified-Since существует также заголовок If-Unmodified-Since. Этот заголовок указывает серверу, что присылать данные нужно, только если они не изменялись после указанной даты.

В HTTP 1.1 был предложен новый подход к управлению кэшированием — E-Tag.

Е-Таg — это уникальный идентификатор, ассоциированный с определенным документом и вычисляемый на основе его содержимого. Если вы думаете о E-Tag, как MD5-хеше содержимого документа, то имеете хорошее представление о нем (фактически хеширование MD5 — это один из способов вычисления E-Tag документа). Идея заключается в том, что если изменился документ, то его E-Tag также изменился. Это упрощает проверку — нужно сверять только значение E-Tag, а не URL вместе с датой модификации.

К тому же, если вы работаете с динамическими документами, им часто недостает даты последней модификации, что дает еще один аргумент в пользу применения E-Tag для управления кэшированием.

Если вы программируете на РНР, то должны использовать функцию header (), чтобы отправит соответствующий E-Tag, как показано ниже в примере:

<?php
Setag = md5($content);
header("ETag: $etag");
?>

При программировании на уровне клиента заголовки If-Match или If-None-Match применяются для проверки специфического E-Tag.