Код на этой странице запрещает кэширование вперед и назад internet explorer как исправить

Обновлено: 02.07.2024

Примечание: По материалам авторского курса «Web-мастеринг. Основы серверного программирования»

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

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

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

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

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

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

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

1

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

2

3

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

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

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

4

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

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). В основном, в таком виде — это команда не для браузера, а для прокси-сервера.

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

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

5

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

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 и убедитесь что раскомментированы следующие строчки (или раскомментируйте их сами):

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

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

6

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

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

Попробуйте пересохранить наш тестовый файл с именем test-4.php и напишите в него следующие строчки:

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

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

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

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

Мы проделали огромное количество улучшений в том как Internet Explorer 9 кэширует данные, для того чтобы увеличить использование ресурсов из кэша. Этот пост описывает эти улучшения, которые уже доступны в третьей версии IE9 Platform Preview, которая была выпущена в прошлом месяце.

Суть кэширования

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

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

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

Хотя RFC2616 рекомендует серверам ограничивать продолжительность жизни контента одним годом, некоторые серверы указывают директивы Cache-Control со значительно большим периодом. До IE9 Internet Explorer признавал устаревшими все ресурсы, период жизни (значение Cache-Control: max-age) которых был больше 2147483648 (2^31) секунд, примерно 68 лет.

В девятой версии IE мы принимаем любое установленное значение max-age вплоть до 2^63, хотя внутри уменьшаем его до 2^31 секунд.

Улучшения параметра Vary

Например, это позволяет серверу возвратить контент на английском с заголовком Vary: Accept-Language. Если пользователь позднее сменит в своем браузере значение Accept-Language с en-US на ja-JP, то ранее кэшированный контент не будет использован, поскольку заголовок Accept-Language больше не совпадает с тем значением, которое было сохранено при кэшировании ресурса на английском.

Кэширование редиректов

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

< 301 Redirect to /SetCookie.asp

< 301 Redirect to /

Здесь, цель сайта установить cookie с помощью вспомогательной страницы, если оно не установлено. Проблема в том, что сервер выбрал 301 для этой задачи и 301 – кэшируется. Как следствие, IE будет просто осуществлять редиректы на стороне клиента без обращения к серверу пока пользователю это не надоест и он не закроет браузер. Учтите, что этот бесконечный цикл будет и в том случае, если cookie запрещены в браузере пользователя.

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

RFC2616 специально указывает на то, что механизм вперед/назад браузеров не должен быть субъектом кэширования:

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

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

В предыдущих версиях IE, когда пользователь переходил вперед или назад, IE проверял обновление ресурсов, если они были посланы с директивой кэша must-revallidate и в зависимости от некоторых других параметров того, как ресурс был получен. В IE9 используется флаг INTERNET_FLAG_FWD_BACK и IE не будет проверять актуальность кэшированных ресурсов когда пользователь переходит по “вперед/назад”.

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int :

В этом примере переменная x является int , и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Первая строка объявляет переменную с именем num , но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception , о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num . Перед созданием объекта вы получите NullPointerException . В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

В этом случае вы не создаете объект obj , скорее предполагая, что он был создан до вызова метода doSomething . К сожалению, этот метод можно вызвать следующим образом:

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException , потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

Настольное приложение Internet Explorer 11 будет снято с службы поддержки 15 июня 2022 г. (список того, что имеется в области, см. в faq). Те же приложения и сайты IE11, которые вы используете сегодня, могут открываться в Microsoft Edge режиме Internet Explorer. Подробнее см. здесь.

Оригинальная версия продукта: Internet Explorer
Исходный номер КБ: 234067

Аннотация

С помощью Microsoft Internet Information Server (IIS) можно легко отметить высокостабильную или чувствительную страницу с помощью следующего сценария в крайнем начале определенных страниц ASP (ASP):

Истечение срока действия и заглавная дата истечения срока действия

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

Во многих случаях веб-серверы имеют одну или несколько волатильных страниц на сервере, которые содержат сведения, которые подлежат немедленному изменению. Эти страницы должны быть помечены сервером со значением "-1" для загона Expires. В случае будущих запросов пользователя Internet Explorer обычно обращается к веб-серверу для обновления этой страницы с помощью условного запроса If-Modified-Since. Однако страница остается в кэше диска (Временные файлы Интернета). И страница используется в соответствующих ситуациях без контакта с удаленным веб-сервером, например:

  • когда кнопки BACK и FORWARD используются для доступа к истории навигации.
  • когда браузер находится в автономном режиме.

Заглавная Cache-Control

Загон Pragma: No-Cache

Параметры сервера для кэшинга

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

Контрольный список проблем

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

Читайте также: