Современные браузеры достаточно часто используют в своей работе локальный кэш. Что это означает? Это означает что браузер, получив от сервера html-документ, картинку или другой ресурс, размещает его в своем локальном кэше (проще говоря, записывает полученный ресурс на жесткий диск машины пользователя) и при последующих запросах к такому ресурсу не обращается на сервер, а получает ресурс из локального кеша.
Данная алгоритм работы браузеров резко повышает скорость загрузки html-документов. Так как если ресурс уже загружался, и как следствие расположен в локальном кэше, то время доступа определяется не пропускной способностью канала связи (например, модемного подключения) а скоростью работы жесткого диска.
Однако наряду с достоинствами данный метод так же порождает ряд проблем. В частности большинство начинающих web-программистов, при разработке динамических сайтов, сталкивается с одной и той же проблемой. Суть этой проблемы заключается в том, что вместо повторного обращения на сервер за страницей, запускающей на сервере скрипт, модифицирующий некую информацию, браузер обращается в локальный кэш. И в результате, например трех обращений, происходит не три модификации информации, расположенной на сервере, а только одна.
Для того, что бы заставить браузер каждый раз обращаться за страницей на сервер необходимо запретить браузеру заносить данный ресурс в кэш. Ниже приведены наиболее распространенные методы, запрещающие кэширование или позволяющие его обойти.
Генерация нового URL
Допустим что запрашиваемый ресурс имеет следующий url: test.html?id=7. Как видно из urlа ему передается один параметр. Добавим, например, при помощи JavaScript, в url еще один параметр, а его значением сделаем случайное число. В результате url будет выглядеть следующим образом: test.html?id=7&rnd=0.6700820127538827. Случайный параметр будет каждый раз генерироваться заново. Ниже приводится листинг, демонстрирующий этот подход:
Каждый раз результат такого запроса будет кэшироваться, но так как кэширование производится по всему url, то каждый раз будет получаться новый url и браузер будет вынужден запрашивать с сервера ресурс, так как url двух запросов не будут совпадать в точности. Поля заголовков
Управлять кэшированием можно так же со стороны сервера. Для этого ресурс, отправляемый браузеру, сопровождается полями заголовка. Детальное описание полей заголовка может быть найдено в стандарте Rfc 2068, который описывает протокол HTTP 1.1.
Поле заголовка Expires
Значением данного заголовка является дата, после которой содержимое ресурса устареет. Если пользователь после этой даты обратиться к ресурсу, браузер должен запросить ресурс у сервера, а не из локального кэша.
Если поле >Expires< содержит дату, прошедшую, по отношению к текущей, то при следующем обращении к ресурсу браузер будет вынужден снова обратиться к серверу. Это произойдет вследствие того, что либо документ не будет занесен в кэш - как уже устаревший, либо при обращении к кэшу браузер определит, что документ уже устарел. Следующий листинг на PHP демонстрирует использование заголовка Expires:
header (Expires: Mon, 26 Jul 1997 05:00:00 GMT);
Поле заголовка Last-Modified
Значением данного заголовка является дата последнего обновления ресурса. Большинство современных браузеров используют следующий алгоритм, если ресурс уже находится в локальном кэше:
* запрашивает с сервера дату последнего обновления ресурса * сравнивает полученную дату и дату ресурса в локальном кэше * если ресурс на сервере новее ресурса в кэше - запрашивается ресурс с сервера
Если ресурс, расположенный на сервере, содержит в данном поле текущую дату, то браузер будет каждый раз запрашивать ресурс с сервера, а не из локального кэша. Следующий листинг демонстрирует использование поля заголовка Last-Modified:
header (Last-Modified: . gmdate(D, d M Y H:i:s) . GMT);
Поля заголовка Cache-Control и Pragma
И, наконец, поля заголовка, непосредственно отвечающие за кэширование ресурса. Поле <Pragma> было определено в стандарте Rfc 1945, описывающим протокол HTTP 1.0. Данное поле считается устаревшим, но в некоторых случаях приходится использовать именно его. В частности некоторые proxy-сервера неправильно обрабатывают запросы к постоянно изменяющимся ресурсам, если вместе с ресурсом не передается данное поле заголовка.
Второе поле определено в стандарте Rfc 2068, который описывает протокол HTTP 1.1. Данное поле заголовка позволяет запретить кэширование, и каждый раз запрашивать ресурс с сервера. Следующий листинг демонстрирует использование полей заголовка Cache-Control и Pragma для запрета кэширования: