Как мне остановить Opera от кэширования страницы? - PullRequest
4 голосов
/ 19 мая 2010

Я пытаюсь заставить Opera повторно запрашивать страницу каждый раз вместо того, чтобы просто обслуживать ее из кэша. Я отправляю заголовки ответов «Cache-control: no-cache» и «Pragma: no-cache», но кажется, что Opera просто игнорирует эти заголовки. Он отлично работает в других браузерах - Chrome, IE, Firefox.

Как мне остановить Opera от кэширования страниц? Я хочу, чтобы Opera повторно запрашивала страницу, когда пользователь нажимает кнопку Назад в браузере.

Ответы [ 4 ]

7 голосов
/ 20 мая 2010

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

Если у вас очень сильный сценарий использования для этого, я бы сказал, что ваша архитектура может быть «неправильной» в некотором смысле - например, если вы переключаетесь между разными «представлениями» постоянного обновления данных и, следовательно, хотите Принудительно ли выполнять повторную загрузку, когда пользователи возвращаются, возможно, будет лучше использовать методы Ajaxy для загрузки постоянно меняющихся данных на текущую страницу?

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

Однако, если вам это действительно нужно, в этой политике есть лазейка, обеспечивающая желаемое поведение. Отправка « Cache-control: must-revalidate » заставит Opera перезагружать каждую страницу при навигации, но только , если вы отправляете страницу через https. (Это функция, запрошенная и предназначенная для параноидальных банков, она замедляет слишком много обычных сайтов, если применяется к http).

2 голосов
/ 20 октября 2017

ПРОСТОЙ СЕРВЕРСИДНЫЙ КОНТРОЛЬ КЭША БЕЗ ЗАГОЛОВОК ИЛИ ПЕРЕДНЕГО СКРИПТА

Нулевая зависимость, Universal Language Edition


Вы можете принудительно выполнитьглобальное кэширование без использования заголовка путем добавления контрольной суммы md5 или sha1 к вашему имени файла.

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

  • Работает во всех браузерах
  • Проверяется как строгий HTML5 (изначально этого не происходило, но это было обновлено. Не проверено для XHTML, но, вероятно, не подходит для этого)
  • Не требует дополнительных заголовков
  • Обеспечивает хорошее разделение интересов внешнего и внутреннего интерфейса.
  • Не требует проверки работоспособности на стороне клиента или проверки источника.
  • Все, что может печатать html, может делать это последовательно, включая статический контент
  • Если не статичный, легко расширить контроль времени выполнения для конечных пользователей (с аутентификацией, если необходимо) , который допускает простые флаги страницдля определения минимизированного, предварительно подтвержденного или отлаживаемого возвращаемого источника.
  • Полностью инкапсулирует управление клиентским кэшем в механизме обслуживания контента, что упрощает обслуживание.
  • В качестве дополнительного преимущества, вводит версионное кэширование на стороне клиента автоматически путем отсчета контрольных сумм, которые кэшировал браузер, что может бытьполезно, если у вас есть альтернативные версии, и вам нужно выполнить модульное тестирование пакета выпуска, чтобы определить его минимальную стабильную версию зависимости или что-то в этом роде.

  • Вам не нужно когда-либо работатьс вашим браузером, чтобы кэширование больше не мешало процессу разработки.

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


Это RFCдействительная разметка.Обратите внимание, что теги script и link имеют строку get:

?checksum=ba411cafee2f0f702572369da0b765e2

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">

  <title>Client Cache Control Example</title>
  <meta name="description" content="You're only going to cache this when the content changes, and always when the content changes.">
  <meta name="author" content="https://stackoverflow.com/users/1288121/mopsyd">

  <!-- Example Stylesheet -->
  <link rel="stylesheet" href="css/styles.css?checksum=ba411cafee2f0f702572369da0b765e2">

  <!-- Example Script -->
  <script src="js/scripts.js?checksum=ba411cafee2f0f702572369da0b765e2"></script>
</head>
<body>
</body>
</html>

Строка GET ?checksum=ba411cafee2f0f702572369da0b765e2 относится к хешу MD5 или SHA1 размера файла:ресурс.Его можно получить с помощью командной строки, языковой конструкции или путем хеширования его по значению заголовка Content-Length:.Затем вы создаете свой атрибут href или src, добавляя его в качестве строки GET к имени файла.

Этот браузер будет интерпретировать их как отдельные и кэшировать отдельно.

Сервер будетигнорируйте параметр GET, если он является статическим ресурсом, но если он обслуживается динамически, то параметр GET будет доступен для языка интерпретации.

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

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

  • Создайте исходный код css или js с помощью любых утилит, которые вы обычно делаете.

  • Запустите контрольную сумму md5 или sha1 для размера файла во время выполнения , если вы обслуживаете динамически, и во время компиляции , если вы генерируете статический контент (например, документы ApiGen)., например) .

  • Служит обычному файлу с хэшем в виде строки GET, добавляемой к имени файла (например: styles.css становится styles.css?checksum=ba411cafee2f0f702572369da0b765e2)

  • Любое изменение в файле приводит к повторной записи, что означает, что вы видите реальное значение, отраженное немедленно.

  • Необязательно, но rad: Дополнительным преимуществом этого подхода является то, что вы можете легко установить флаг dev GET, который заставит ВСЕ интерфейсные исходные коды преобразовываться в предварительно подтвержденный источник dev с любым из ваших включить собственную настраиваемую функцию отладки или использовать ее для интерпретации флагов управления версиями. Вы можете выполнить избыточную проверку, чтобы убедиться, что флаг передается только с известного IP-адреса разработки, проверки подлинности прокси-сервера и т. Д. Сервером, и в противном случае он не учитывается, если вам требуется его безопасность. Я обычно делю свой внешний интерфейс по возможности, как это:

    • Это то, что он делает в прямом эфире прямо сейчас (минимизированное производство, кэширование, по умолчанию, ?checksum=ba411cafee2f0f702572369da0b765e2).
    • Это то, что он должен делать в прямом эфире прямо сейчас, достаточно предварительно для того, чтобы я мог читать (предварительно обработанное производство, никогда не кэшируется , ?debug_pretty_source=true).
    • Это то, что я использую, чтобы выяснить, что не делает то, что должно быть вживую, если оно существует в обоих предыдущих (предварительно подтверждено с включенной отладкой, никогда не кэшируется , ACL / белый список разрешен, ?debug_dev_enable=true или аналогичный ).

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

2 голосов
/ 20 мая 2010

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

0 голосов
/ 22 марта 2013

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

В <HEAD> выше любого другого JavaScript:

<script>
    if( typeof(opera) != 'undefined' ) { // only do for Opera
       if (window.name == 'previously_loaded') { // will be "" before page is loaded
            alert('Reloading Page from Server'); // for testing
            window.name = ''; // prevent multiple reload
            window.location.reload(true);
       }
    }
</script>

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

window.name = 'previously_loaded';

Вставьте эту строку в один из ваших js-блоков, которые не будут выполняться во время «загрузки окна», вызывая бесконечную перезагрузку. Для меня не было необходимости обновлять страницу, если кто-то не вышел по ссылке, поэтому я просто добавил ее в свою функцию onclick / onunload.

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

Редактировать: Просто понял, что если позже посещенный сайт изменит имя окна (его постоянное), то перезагрузка с обратной вкладкой не произойдет. Просто измените вышеприведенное выражение if на:

 if (window.name != "") {

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

window.name = new Date().getTime();
...