Как запретить кэширование страницы. Запрет кэширования посредством PHP

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


Речь здесь не о том, как запретить кэш лишь в браузере, а о том, как запретить кэширование контента на стороне сервера. Многим наверно известны методы запрета кэширования в заголовках HTML-страниц, например упомянутые в Wikipedia, такие как

Кроме того можно использовать и такие

В первой строке указывается рекомендация запрещать кэширование вообще, а вторая строка указывает браузеру, что страница используется в приватном режиме, поэтому ее содержимое не должно кэшироваться. Мета-теги в третьей и четвертой строках указывают на то, что срок хранения в кэше ограничено временем max-age=10800 (что равно 3-м часам) для браузера и для прокси соответственно.

Приведенные выше в пример рекомендации хороши однако лишь для тех владельцев сайтов, у которых нет доступа к PHP-скриптам, и больше подходят для нединамических страниц. Это, как говорится, «последний шанс», и лишь потому, что многие браузеры, да к тому же их многочисленные версии, все меньше и меньше обращают внимание на то, что прописано в HEAD-секциях страниц сайтов. Каждый из них «тянет одеяло на себя» и не все и не всегда придерживаются каких-то стандартов. Другими словами то, что было сказано выше, может не сработать.

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

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

Вот пример простого указания сроков кэширования страниц сайта:

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

В некоторых случаях может пригодиться в параметре заголовка использовать дополнительные параметры post-check=0 и pre-check=0

Header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); ...

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

$echo = " Ссылка "; $echo = "";

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

Проверка, что кэширование отключено

Проверить, кэшируется ли страница или нет, можно с помощью добавления времени сервера, в которое была сгенерирована конкретная страница, непосредственно в код страницы. Это легко сделать с помощью PHP

В строке №6 содержится код date("H:i:s") , который показывает точное серверное время, в которое страница была создана. Таким образом, при каждом запросе к странице, при условии, что кэширование полностью отключено, мы всегда будем видеть абсолютно новое время. Если все же кэширование выполняется, то при частых запросах страница будет содержать одно и то же время.

Запрет кэширования страниц средствами Apache .htaccess

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

Добавив в файл.htaccess, который находился в каталоге скриптов веб-чата, следующие установки, я решил проблему:

Header append Cache-Control "no-store, no-cache, must-revalidate" ExpiresActive On ExpiresDefault "now"

Так что тем, для кого проблема запрета кэширования страниц сайта является актуальной, то рекомендую использовать метод средствами файлов.htaccess сервера Apache. Правда это будет тоже работать лишь при условии, что на вашем хостинге будут загружены и подключены соответствующие модули - mod_expires.so и mod_headers.so . Подключены они или нет, можно будет убедиться при просмотре конфигурационного файла Apache, панели управления на хостинге или, в крайнем случае, обратившись с вопросом к тех.поддержке хостинга.

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

Если же эти модули у вас подключены, то вы можете манипулировать и кэшированием отдельных файлов, например добавив в.htaccess такие директивы:

ExpiresActive On ExpiresDefault "now" Header append Cache-Control must-revalidate ExpiresDefault "now"

Кроме того, Вы сможете указывать время ограничения кэширования, например:

ExpiresDefault "access plus 1 month" # или # ExpiresDefault "access plus 4 weeks" # или # ExpiresDefault "access plus 30 days"

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

ExpiresByType text/html "access plus 1 month 7 days 12 hours" ExpiresByType image/gif "modification plus 3 hours 15 minutes"

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

Как запретить кэширование?

Ответ мастера:

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

Сделаем следующее, если используется Mozilla Firefox. В адресную строку браузера вписываем opera:config. Появится окно, которое предупредит о том, что нужно быть предельно острожным. Нажмем «Ок». Находим «Фильтр», там набираем browser.cache. После этого в настройках останется не более десяти строчек.

Для отключения кэширования найдем browser.cache.disk.enable и browser.cache.memory.enable. Заострим внимание на поле значения. Обе этих строчки имеют значение true. Изменим его на false. После этого перезапустим браузер, для того чтобы все изменения вступили в силу. 2.Сделаем следующее, если используется Internet Explorer. В меню откроем «Сервис», далее жмем по окно «Свойства обозревателя». Откроется окно свойств браузера. Переходим к вкладке «Общие», там нажимаем «Параметры».

Затем в селекторе «Проверять наличие обновления сохраненных страниц» выберем «Никогда». Для запрета кэширования поставим ноль возле окна «Используемое место на диске». После этого нажимаем «Ок» для принятия изменений.

Если используется Opera. Нажмем клавиши Ctrl+F12, далее выберем «Общие настройки». Перейдем к вкладке «Расширенные», потом к «Истории». Вкладке «Кэш в памяти», а также «Дисковый кэш» присвоим значение «Отключено» для отмены кэширования. В окнах «Проверять документы» и «Проверять изображения» выберем «Никогда». Далее «Ок», изменения вступят в силу.

Если используется Google Chrome. Нажмем правой кнопкой мышки на ярлык запуска браузера. После появления контекстного меню выберем окно «Свойства». После этого в появившемся окне перейдем на вкладку «Ярлык». В окне, где указан адрес файла, допишем “-disk-cache-size=0-media-cache-size=0”. Поместим данную команду за кавычками адреса файла. Применим изменения.

Современные браузеры достаточно часто используют в своей работе локальный кэш. Что это означает? Это означает что браузер, получив от сервера 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");

Порой, бывает необходимо запрещать браузеру кэшировать страницу, так как информация на ней обновляется каждый раз. Это может быть генерация данных, соответственно выбранным фильтрам или другой контент, который каждый раз создается по-новому. Одним словом, бывают моменты, когда необходимо запретить коварной программе кэшировать страницу. Сегодня, мы узнаем, как реализовать это разными способами, с помощью 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"

Заключение

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

Порой, бывает необходимо запрещать браузеру кэшировать страницу, так как информация на ней обновляется каждый раз. Это может быть генерация данных, соответственно выбранным фильтрам или другой контент, который каждый раз создается по-новому. Одним словом, бывают моменты, когда необходимо запретить коварной программе кэшировать страницу. Сегодня, мы узнаем, как реализовать это разными способами, с помощью 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"