Php запрет кэширования страницы. Запрет кэширования страницы на HTML, PHP, htaccess

Порой, бывает необходимо запрещать браузеру кэшировать страницу, так как информация на ней обновляется каждый раз. Это может быть генерация данных, соответственно выбранным фильтрам или другой контент, который каждый раз создается по-новому. Одним словом, бывают моменты, когда необходимо запретить коварной программе кэшировать страницу. Сегодня, мы узнаем, как реализовать это разными способами, с помощью PHP или HTML или.htaccess.

Запрет кэширования страницы на HTML

Сделать это можно с помощью мета тегов. Сейчас мы разберем разные варианты запрета на кэширование.

Запрет на кэширование браузером и прокси-сервером

Запрет кэширования страницы, только браузером

Установка кэширования на определенное время, для браузера

С помощью кода ниже, мы можем сообщить браузеру, сколько хранить документ в кэше. После чего, кэш будет обновлен.

Установка кэширования на определенное время, для прокси-сервера

Практически, то же самое, что и в предыдущем коде, только указание стоит конкретно для прокси-сервера.

Запретить кэширование страницы с помощью PHP

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

Также, можно разрешать кэшировать на определенное время. Например, разрешим кэширование только на 1 час.

Запретить кэширование страницы с помощью.htaccess

Для простоты реализации идеи, можно все сделать на уровне конфигураций сервера Apache. Перед этим, нам нужно убедиться в том, что необходимые модули находятся в рабочем состоянии. Открываем конфигурационный файл Apache и наблюдаем следующую картину:

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

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

# Заголовок Cache-Control Header append Cache-Control "no-store, no-cache, must-revalidate" # Заголовок Expires ExpiresActive On ExpiresDefault "now"

Важно заметить, что полный запрет кэширования, повышает нагрузку на сервер. Поэтому, играйтесь с этим осторожно! А лучше, установите определенное время, на которое можно кэшировать документы. Например, установим кэширование на 1 час:

# Заголовок Cache-Control Header append Cache-Control "public" # Заголовок Expires ExpiresActive On ExpiresDefault "access plus 1 hours"

Заключение

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

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

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

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

Генерация нового URL

Допустим что запрашиваемый ресурс имеет следующий url: test.html?id=7. Как видно из url’а ему передается один параметр. Добавим, например, при помощи JavaScript, в url еще один параметр, а его значением сделаем случайное число. В результате url будет выглядеть следующим образом: test.html?id=7&rnd=0.6700820127538827. Случайный параметр будет каждый раз генерироваться заново. Ниже приводится листинг, демонстрирующий этот подход:

Генерация нового URL document.write (""); тестовая ссылка

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

Управлять кэшированием можно так же со стороны сервера. Для этого ресурс, отправляемый браузеру, сопровождается полями заголовка. Детальное описание полей заголовка может быть найдено в стандарте Rfc 2068, который описывает протокол HTTP 1.1.

Поле заголовка Expires

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

Если поле >Expires< содержит дату, прошедшую, по отношению к текущей, то при следующем обращении к ресурсу браузер будет вынужден снова обратиться к серверу. Это произойдет вследствие того, что либо документ не будет занесен в кэш — как уже устаревший, либо при обращении к кэшу браузер определит, что документ уже устарел. Следующий листинг на PHP демонстрирует использование заголовка Expires:

Поле заголовка Last-Modified

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

* запрашивает с сервера дату последнего обновления ресурса
* сравнивает полученную дату и дату ресурса в локальном кэше
* если ресурс на сервере новее ресурса в кэше — запрашивается ресурс с сервера

Если ресурс, расположенный на сервере, содержит в данном поле текущую дату, то браузер будет каждый раз запрашивать ресурс с сервера, а не из локального кэша. Следующий листинг демонстрирует использование поля заголовка Last-Modified:

header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

Поля заголовка Cache-Control и Pragma

И, наконец, поля заголовка, непосредственно отвечающие за кэширование ресурса. Поле Было определено в стандарте Rfc 1945, описывающим протокол HTTP 1.0. Данное поле считается устаревшим, но в некоторых случаях приходится использовать именно его. В частности некоторые proxy-сервера неправильно обрабатывают запросы к постоянно изменяющимся ресурсам, если вместе с ресурсом не передается данное поле заголовка.

Второе поле определено в стандарте Rfc 2068, который описывает протокол HTTP 1.1. Данное поле заголовка позволяет запретить кэширование, и каждый раз запрашивать ресурс с сервера. Следующий листинг демонстрирует использование полей заголовка Cache-Control и Pragma для запрета кэширования:

header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache");

Хорошо Плохо

Немного о кэшировании

Веб-мастера часто сталкиваются с кэшированием: браузеры и прокси-сервера, пытаясь ускорить работу Веба для пользователя, стараются сохранить у себя максимально большое количество документов в кэше. Если вы открываете страницу сайта в браузере, потом еще одну, и после этого возвращаетесь на первую, с великой долей вероятности браузер возьмет ее с вашего диска (а то и из оперативной памяти), куда он сохранил страницу при первом посещении. Понятно, эта операция, как правило, выполняется намного быстрее, чем получение того же документа из сети. Ведь для отображения страницы нужно не только получить HTML код, но и выкачать из сети все сопутствующие документы: CSS-файлы, картинки, скрипты, оформленные в виде отдельных файлов, и т.д. Если вы посмотрите в папки кэша на вашем диске (для IE эта папка обычно находится здесь: «C:\Documents and Settings\имя_пользователя \Local Settings\Temporary Internet Files», для Firefox: «C:\Documents and Settings\имя_пользователя \Local Settings\Application Data\Mozilla\Firefox\Profiles\_случайная_строка_. default\Cache»), то вы заметите, сколько файлов было сохранено вашим браузером.

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

Проблема с кешированием в Microsoft Internet Explorer

Internet Explorer кеширует GET-запросы. Те авторы, которые не знакомы с кешированием HTTP, ожидают, что GET-запросы не кешируются, или что кеш может быть обойдён, как в случае нажатия кнопки обновления. В некоторых ситуациях избегание кеширования действительно является ошибкой. Одним из решений является использование метода POST, который никогда не кешируется; однако он предназначен для других операций. Другим решением является использование метода запроса GET, включающего уникальную строку запроса с каждым вызовом, как показано на примере ниже.

req.open("GET", "xmlprovider.php?hash=" + Math.random());

или установки заголовка Expires на прошедшую дату в вашем скрипте, который генерирует содержимое XML. В PHP это будет так:

// disable IE caching header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); ...

Знакомый PHP код? Уверен, вы его писали (как правило, методом Copy -Paste ) в своих наработках. Но! Здесь есть очень существенное «НО»: ни в коем случае не умаляя важности и авторитетности Википедии, отметим лишь тот прискорбный факт, что этот код ОШИБОЧЕН! Хотите убедиться? Легко!

Проверяем кэширование

Итак, запустим Apache со стандартными, дефолтовыми настройками. Здесь и далее мы используем Apache и PHP. Но это ни в коем случае не говорит, что описываемой проблемы и вариантов ее решения нет на платформе других серверов, например, у Microsoft IIS. Итак, запустим Apache. Создайте пустую папку test-cache в корне сервера и поместите туда файл test-1.php со следующим содержанием:

Легко увидеть, что в приведенном примере мы пытаемся запретить кэширование по рецепту Википедии, и просто выводим текущее время.

Теперь попробуйте посмотреть вашу папку в браузере. Для этого откройте свой браузер и наберите в адресной строке

Отлично! Теперь щелкните по своему файлу test-1.php и запомните время (для примера я разместил окно браузера рядом с часами Windows):

Великолепно! Теперь нажмите в браузере кнопки «Назад» и потом «Вперед»:

Упc! Время не меняется!!! А что это значит? Да только то, что браузер берет страницу из кэша!!! А как же наш энциклопедичный код? Да он не работает!

Обратимся к первоисточникам

В чем же проблема? Проблема в неправильном использовании заголовков ответа. В спецификации RFC2616 кэшированию посвящена целая глава. Но, к сожалению, веб-мастера не часто читают спецификации. Итак, что же обозначают те заголовки, которые мы только что передали? Давайте их посмотрим. Это очень удобно делать с помощью дополнения к браузеру Firefox Web Developer Toolbar : Information . View Response Headers (для IE похожий инструмент называется DevToolbar):

Итак, мы передали следующие заголовки:

Expires : Mon , 26 Jul 1997 05:00:00 GMT — этот заголовок устанавливает время актуальности информации. Мы же пытаемся передать дату в прошлом, полагая, что это заставит браузер каждый раз загружать страницу с сервера. Не заставляет, как мы хорошо заметили на опыте.

Last -Modified : Sat , 26 Jan 2008 17:03:02 GMT — Дата и время изменения информации на странице. Этот заголовок ВООБЩЕ никак не влияет на кэширование (читаем в RFC2616!), разве что может использоваться для запроса с валидаторами. Например, поисковый робот может запросить данные так: GET /megapage.html HTTP/1.1 If-Mofidied-Since: Sat, 26 Jan 2008 17:03:02 GMT

То есть, «дай документ, если он изменился с указанной даты », и сервер должен ответить или 200 («Вот документ, он изменился!» или 304 «Изменений не было». Но чтобы это работало, ваш сервер ДОЛЖЕН передавать заголовок Last-Modified, и не просто передавать, а передавать ПРАВИЛЬНУЮ ДАТУ изменения документа. Но мы сами, своими руками, и бестолковым энциклопедическим кодом полностью разрушили последние надежды на это! То есть, мало того, что мы кэш не запретили, мы еще и поисковикам (а точнее, СЕБЕ) основательно нагадили! Ведь вы передали ТЕКУЩУЮ дату, как дату последнего изменения, помните?

Cache-Control: no-cache, must-revalidate — вот, уже ближе к теме. Именно этот заголовок управляет кэшированием, но не сам, а в совокупности с другими. Сейчас же мы просто передали следующую команду: «использовать информацию следующего запроса без повторной проверки на исходном сервере нельзя» (If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server). В основном, в таком виде — это команда не для браузера, а для прокси-сервера.

Pragma: no-cache — устаревшая конструкция. Это из старой версии протокола HTTP/1.0. Практически все браузеры и прокси ее игнорируют. Итак, мы видим, что ни одна из наших строчек PHP кода реально кэш не запретила. Что же делать? А вот что:

Запрет кэширования

Пересохраните файл test-1.php с новым именем test-2.php и измените его следующим образом:

Теперь попробуйте снова открыть нашу тестовую папку http://localhost/test-cache/ , щелкните по имени test-2.php и теперь наживайте кнопки «Назад», «Вперед». Время каждый раз меняется! И это говорит о том, что браузер не берет страницу из кэша при переходе вперед/назад, а заново запрашивает ее с сервера. Что, собственно, нам было и нужно. Давайте посмотрим заголовки ответа:

Вот оно! Мы передаем два заголовка:

Cache -Control : no -store — страница содержит приватные данные, сохранять в кэше нельзя! (The purpose of the no-store directive is to prevent the inadvertent release or retention of sensitive information (for example, on backup tapes))

Expires : Sat , 26 Jan 2008 20:31:55 +0300 — актуальность страницы истекает мгновенно, то есть сейчас.

И именно эти заголовки запрещают кэширование в браузере. Но все же более правильно дописать в заголовок Cache-Control инструкции и для прокси-серверов (файл test-3.php):

Практическое запрещение кэширования

Таким образом, мы научились выключать кэш. Значит ли это, что нужно приведенный выше код включать во все ваши страницы? Совсем нет! Если вам нужно запретить кэширование во всех файлах папки (а не только для исполняемых php скриптов) можно настроить сервер Apache на передачу нужных нам заголовков. Для этого откройте файл конфигурации сервера Apache и убедитесь что раскомментированы следующие строчки (или раскомментируйте их сами):

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

Отлично! Теперь просто создайте в своей папке файл.htaccess и впишите в него следующее:

# # Запрещение кеширования в этой папке # Необходимо включение модулей # mod_headers.c и mod_expires.c # # Заголовок Cache-Control Header append Cache-Control "no-store, no-cache, must-revalidate" # Заголовок Expires ExpiresActive On ExpiresDefault "now"

Все! Необходимые заголовки передаются автоматически, и специально из писать в PHP уже не нужно — кэш уже выключен! В этом легко убедится, если посмотреть заголовки, передаваемые при запросе ЛЮБОГО файла этой папки:

Разрешение кэширования

Но, несмотря на то, что подавляющее число веб-мастеров, считают кэш вселенским злом, и пытаются запретить его (и как мы увидели, весьма безуспешно), это не так! Запретив кэширование, вы заставляете браузер каждый раз заново загружать ваши страницы с сервера, и если канал связи у пользователя слабый, то это может привести к заметному замедлению работы с вашим сайтом. Я уже не говорю о том, что это приводит к возрастанию нагрузки на ваш сервер! Если ваша страница или ее часть формируется запросами в БД, вы, к тому же, увеличиваете нагрузку на сервер БД, что крайне негативно может сказаться на производительности вашего сервера в целом. Вы же понимаете, о чем я говорю, например, посмотрите на работу www.odnoklassniki.ru ! Некоторые веб-мастера еще и хвастаются, выводя этакую «статистику» внизу страницы: «Страница сформирована за 0.9 сек, выполнено 9 SQL запросов ». Ничего, кроме абсолютно бестолковой архитектуры Веб-приложения, это не показывает!

Так давайте же наоборот постараемся разгрузить сервер, и ускорить работу нашего пользователя! И кэш в этом деле — один из мощных инструментов! Ну скажите пожалуйста, как часто меняется ваша страница «О компании»? Или что случится, если пользователь увидит вашу новость («ура! Мы переехали на новый движок ») ЧАСОМ ПОЗЖЕ? Так зачем же запрещать кэширование таких страниц

Теперь откройте его с помощью браузера, запомните время и попробуйте переходить по разным ссылкам на этот файл. Время не меняется, даже если вы закроете браузер, откроете и заново щелкните по имени файла! В течение часа этот файл будет браться из кэша. То есть в течение часа для пользователя ваш скрипт выполнится ОДИН РАЗ, все остальное время, страница будет загружаться из локального кэша С МАКСИМАЛЬНО ВОЗМОЖНОЙ СКОРОСТЬЮ! И представьте, во сколько раз снизится нагрузка на ваш сервер! И это всего две строчки в коде!

А можно и вообще без PHP обойтись. Создайте в папке файл.htaccess и впишите в него следующее:

# # Разрешение кеширования в этой папке # Необходимо включение модулей # mod_headers.c и mod_expires.c # # Заголовок Cache-Control Header append Cache-Control "public" # Заголовок Expires ExpiresActive On ExpiresDefault "access plus 1 hours"

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

Только рекомендация: сначала полностью отладьте ваш сайт и только после этого включайте кэширование! Иначе вы рискуете в поисках ошибок поседеть и полностью разочароваться в Веб-технологиях:)
Успехов вам и удачи с кэшированием!

Сколько раз писано и переписано о тэге … Казалось бы, все! Хватит! Закрыли тему! Но нет! Ведь не все сказали! Вернее, кое-где все, но это попробуй найди еще. Потыкайся во всякие Rambler’s и Яndex’ы…

Итак, поговорим о кэшировании. Собственно, для чего оно нужно всем нам, бедным пользователям интернета, как среды обитания. Сокращение трафика — вот она, польза! Ну зачем нам десять раз на день заново качать из сети первую страницу какого-нибудь поискового каталога, когда можно аккуратненько положить ее в кэш и забыть о медленной загрузке для этого сайта? Во-от, именно так и делают. Углубимся в проблему.

Всем известно, что разных версиях протоколов HTTP применяются свои директивы управления кэшированием. Cache-Control — директива протокола HTTP/1.1. А параметры у нее вот такие:

Все перечисленные атрибуты (кроме взаимоисключающих) можно перечислять через запятую. Понимаю, не все ясно, сейчас кое-что поясню.

1. Запрет на кэширование вообще (документ не будет кэшироваться ни proxy-сервером, ни браузером):

2. Документ будет кэшироваться браузером, но не будет кэшироваться proxy-сервером.

3. Документ будет кэшироваться, даже если и не должен, вроде бы, при обычных обстоятельствах.

4. Документ кэшируется, но не сохраняется в архиве.

5. Можно прямо сказать браузеру: «Обнови-ка мне эту страницу». (В параметре max-age указано, на сколько секунд кэшируется документ). Может быть полезно при использовании PHP для програмного обновления страниц.

6.А можно сказать это только прокси-серверу.

В наследство от протокола HTTP 1.0 нам достался очень простой способ управления кэшированием, определяется директивой Pragma. Данная штука является общей директивой заголовка HTTP-сообщения в HTTP/1.0, и других значений, кроме no-cahce, не имеет:

В протоколе HTTP 1.1 данная директива заменена директивой Cache-Control со значением no-cache. Большинство серверов и клиентов поддерживают эту директиву и правильно ее отрабатывают.

Для запрета на кэширование иногда не достаточно применения директив управления кэшированием. Так Netscape кэширует документы или их компоненты даже при наличии директив Cache-Control и Pragma. Для того, чтобы заставить перечитать компонент страницы (он ведь получается с сервера по самостоятельному HTTP-запросу) можно установить директиву Expires.

Вот такой вот получился разговор о кэшировании. А с тэгом META мы еще встретимся. И не раз…

Хорошо Плохо

    Мета теги - это необязательные аттрибуты страницы, размещенные в ее заголовке, которые содержат описание страницы, ключевые слова к ней, некоторую информацию об…

Описание кэширования. Решение проблем с различными браузерами и описание заголовков ответов сервера, отвечающих за кэширование.

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

Понятно, эта операция, как правило, выполняется намного быстрее, чем получение того же документа из сети. Ведь для отображения страницы нужно не только получить HTML код, но и выкачать из сети все сопутствующие документы: CSS-файлы, картинки, скрипты, оформленные в виде отдельных файлов, и т.д. Если вы посмотрите в папки кэша на вашем диске (для IE эта папка обычно находится здесь: «C:\Documents and Settings\имя_пользователя \Local Settings\Temporary Internet Files», для Firefox: «C:\Documents and Settings\имя_пользователя \Local Settings\Application Data\Mozilla\Firefox\Profiles\_случайная_строка_. default\Cache»), то вы заметите, сколько файлов было сохранено вашим браузером.

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

Например, если будет кэшироваться страница чата, то пользователи просто не увидят новые сообщения. Веб-мастера часто считают кэш злом, и борются с этим злом в меру своих сил.

Проблема с кешированием в Microsoft Internet Explorer

Internet Explorer кеширует GET-запросы. Те авторы, которые не знакомы с кешированием HTTP, ожидают, что GET-запросы не кешируются, или что кеш может быть обойдён, как в случае нажатия кнопки обновления. В некоторых ситуациях избегание кеширования действительно является ошибкой. Одним из решений является использование метода POST, который никогда не кешируется; однако он предназначен для других операций. Другим решением является использование метода запроса GET, включающего уникальную строку запроса с каждым вызовом, как показано на примере ниже.

Req.open("GET", "xmlprovider.php?hash=" + Math.random());

или установки заголовка Expires на прошедшую дату в вашем скрипте, который генерирует содержимое XML. В PHP это будет так:

// disable IE caching header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); ...

Знакомый PHP код? Уверен, вы его писали (как правило, методом Copy-Paste ) в своих наработках. Но! Здесь есть очень существенное «НО»: ни в коем случае не умаляя важности и авторитетности Википедии, отметим лишь тот прискорбный факт, что этот код ОШИБОЧЕН! Хотите убедиться? Легко!

Проверяем кэширование

Итак, запустим Apache со стандартными, дефолтовыми настройками. Здесь и далее мы используем Apache и PHP. Но это ни в коем случае не говорит, что описываемой проблемы и вариантов ее решения нет на платформе других серверов, например, у Microsoft IIS. Итак, запустим Apache. Создайте пустую папку test-cache в корне сервера и поместите туда файл test-1.php со следующим содержанием:

Легко увидеть, что в приведенном примере мы пытаемся запретить кэширование по рецепту Википедии, и просто выводим текущее время.

Статья по теме: Недорогой хостинг с индивидуальной конфигурацией

Теперь попробуйте посмотреть вашу папку в браузере. Для этого откройте свой браузер и наберите в адресной строке

Отлично! Теперь кликните по своему файлу test-1.php и запомните время (для примера я разместил окно браузера рядом с часами Windows):

Великолепно! Теперь нажмите в браузере кнопки «Назад» и потом «Вперед»:

Упc! Время не меняется!!! А что это значит? Да только то, что браузер берет страницу из кэша!!! А как же наш энциклопедичный код? Да он не работает!

Обратимся к первоисточникам

В чем же проблема? Проблема в неправильном использовании заголовков ответа. В спецификации RFC2616 кэшированию посвящена целая глава. Но, к сожалению, веб-мастера не часто читают спецификации. Итак, что же обозначают те заголовки, которые мы только что передали? Давайте их посмотрим. Это очень удобно делать с помощью дополнения к браузеру Firefox Web Developer Toolbar : Information. View Response Headers (для IE похожий инструмент называется DevToolbar):

Итак, мы передали следующие заголовки:

Expires: Mon, 26 Jul 1997 05:00:00 GMT - этот заголовок устанавливает время актуальности информации. Мы же пытаемся передать дату в прошлом, полагая, что это заставит браузер каждый раз загружать страницу с сервера. Не заставляет, как мы хорошо заметили на опыте.

Last-Modified: Sat, 26 Jan 2008 17:03:02 GMT - Дата и время изменения информации на странице. Этот заголовок ВООБЩЕ никак не влияет на кэширование (читаем в RFC2616!), разве что может использоваться для запроса с валидаторами. Например, поисковый робот может запросить данные так:

То есть, «дай документ, если он изменился с указанной даты », и сервер должен ответить или 200 («Вот документ, он изменился!» или 304 «Изменений не было». Но чтобы это работало, ваш сервер ДОЛЖЕН передавать заголовок Last-Modified, и не просто передавать, а передавать ПРАВИЛЬНУЮ ДАТУ изменения документа. Но мы сами, своими руками, и бестолковым энциклопедическим кодом полностью разрушили последние надежды на это! То есть, мало того, что мы кэш не запретили, мы еще и поисковикам (а точнее, СЕБЕ) основательно нагадили! Ведь вы передали ТЕКУЩУЮ дату, как дату последнего изменения, помните?

Cache-Control: no-cache, must-revalidate - вот, уже ближе к теме. Именно этот заголовок управляет кэшированием, но не сам, а в совокупности с другими. Сейчас же мы просто передали следующую команду: «использовать информацию следующего запроса без повторной проверки на исходном сервере нельзя» (If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server). В основном, в таком виде - это команда не для браузера, а для прокси-сервера.

Статья по теме: Какой выбрать хостинг для сайта на WordPress: советы новичку

Pragma: no-cache - устаревшая конструкция. Это из старой версии протокола HTTP/1.0. Практически все браузеры и прокси ее игнорируют. Итак, мы видим, что ни одна из наших строчек PHP кода реально кэш не запретила. Что же делать? А вот что:

Запрет кэширования

Пересохраните файл test-1.php с новым именем test-2.php и измените его следующим образом:

Теперь попробуйте снова открыть нашу тестовую папку //localhost/test-cache/ , щелкните по имени test-2.php и теперь наживайте кнопки «Назад», «Вперед». Время каждый раз меняется! И это говорит о том, что браузер не берет страницу из кэша при переходе вперед/назад, а заново запрашивает ее с сервера. Что, собственно, нам было и нужно. Давайте посмотрим заголовки ответа:

Вот оно! Мы передаем два заголовка:

Cache-Control: no-store - страница содержит приватные данные, сохранять в кэше нельзя! (The purpose of the no-store directive is to prevent the inadvertent release or retention of sensitive information (for example, on backup tapes))

Expires: Sat, 26 Jan 2008 20:31:55 +0300 - актуальность страницы истекает мгновенно, то есть сейчас.

И именно эти заголовки запрещают кэширование в браузере. Но все же более правильно дописать в заголовок Cache-Control инструкции и для прокси-серверов (файл test-3.php):

Практическое запрещение кэширования

Таким образом, мы научились выключать кэш. Значит ли это, что нужно приведенный выше код включать во все ваши страницы? Совсем нет! Если вам нужно запретить кэширование во всех файлах папки (а не только для исполняемых php скриптов) можно настроить сервер Apache на передачу нужных нам заголовков. Для этого откройте файл конфигурации сервера Apache и убедитесь что раскомментированы следующие строчки (или раскомментируйте их сами):

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

Отлично! Теперь просто создайте в своей папке файл.htaccess и впишите в него следующее:

# # Запрещение кеширования в этой папке # Необходимо включение модулей # mod_headers.c и mod_expires.c # # Заголовок Cache-Control Header append Cache-Control "no-store, no-cache, must-revalidate" # Заголовок Expires ExpiresActive On ExpiresDefault "now"

Все! Необходимые заголовки передаются автоматически, и специально из писать в PHP уже не нужно - кэш уже выключен! В этом легко убедится, если посмотреть заголовки, передаваемые при запросе ЛЮБОГО файла этой папки:

Разрешение кэширования

Но, несмотря на то, что подавляющее число веб-мастеров, считают кэш вселенским злом, и пытаются запретить его (и как мы увидели, весьма безуспешно), это не так! Запретив кэширование, вы заставляете браузер каждый раз заново загружать ваши страницы с сервера, и если канал связи у пользователя слабый, то это может привести к заметному замедлению работы с вашим сайтом. Я уже не говорю о том, что это приводит к возрастанию нагрузки на ваш сервер! Если ваша страница или ее часть формируется запросами в БД, вы, к тому же, увеличиваете нагрузку на сервер БД, что крайне негативно может сказаться на производительности вашего сервера в целом. Вы же понимаете, о чем я говорю, например, посмотрите на работу Одноклассники.ру! Некоторые веб-мастера еще и хвастаются, выводя этакую «статистику» внизу страницы: «Страница сформирована за 0.9 сек, выполнено 9 SQL запросов ». Ничего, кроме абсолютно бестолковой архитектуры Веб-приложения, это не показывает!