Предотвращение кэширования iframe в браузере - PullRequest
76 голосов
/ 15 апреля 2010

Как запретить Firefox и Safari кэшировать содержимое iframe?

У меня есть простая веб-страница с iframe для страницы на другом сайте. И внешняя страница, и внутренняя страница имеют заголовки ответа HTTP для предотвращения кэширования. Когда я нажимаю кнопку «назад» в браузере, внешняя страница работает правильно, но, несмотря ни на что, браузер всегда извлекает кэш страницы в фрейме. IE работает просто отлично, но Firefox и Safari доставляют мне неприятности.

Моя веб-страница выглядит примерно так:

<html>
  <head><!-- stuff --></head>
<body>
  <!-- stuff -->
  <iframe src="webpage2.html?var=xxx" />
  <!-- stuff -->
</body>
</html>

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

Я изучил HTTP-запросы и ответы, идущие туда-сюда, и заметил, что даже если внешняя страница содержит <iframe src="webpage2.html?var=222" />, браузер все равно будет получать webpage2.html?var=111.

Вот что я пробовал до сих пор:

  • Изменение URL-адреса iframe со случайным значением var
  • Добавление заголовков Expires, Cache-Control и Pragma на внешнюю веб-страницу
  • Добавление заголовков Expires, Cache-Control и Pragma на внутреннюю веб-страницу

Я не могу выполнять какие-либо трюки с JavaScript, потому что заблокирован политикой того же происхождения.

У меня заканчиваются идеи. Кто-нибудь знает, как остановить кеширование браузером содержимого iframed?

Обновление

Я установил Fiddler2, поскольку Даниэль предложил провести еще один тест, и, к сожалению, я все еще получаю те же результаты.

Это тест, который я выполнил:

  1. На внешней странице генерируется случайное число с использованием Math.random() в JSP.
  2. На внешней странице отображается случайное число на веб-странице.
  3. Внешняя страница вызывает iframe, передавая случайное число.
  4. На внутренней странице отображается случайное число.

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

Визуальный тест

Для быстрого теста я загружаю страницу, перехожу на другую страницу и затем нажимаю «назад». Вот результаты:

Исходная страница:

  • Наружная страница: 0.21300034290246206
  • Внутренняя страница: 0.21300034290246206

Покинуть страницу, затем вернуться назад:

  • Наружная страница: 0,4470929019483644
  • Внутренняя страница: 0,21300034290246206

Это показывает, что внутренняя страница кэшируется, хотя внешняя страница вызывает ее с другим параметром GET в URL. По какой-то причине браузер игнорирует тот факт, что iframe запрашивает новый URL; он просто загружает старый.

Тест Скрипача

Конечно, Фиддлер подтверждает то же самое.

(Я загружаю страницу.)

Внешняя страница называется. HTML:

0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />

http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206 называется.

(Я отхожу от страницы, а затем нанослю ответный удар).

Внешняя страница называется. HTML:

0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />

http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206 называется.

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

У кого-нибудь есть идеи, как запретить веб-браузеру кэшировать URL-адреса iframe?

Ответы [ 13 ]

46 голосов
/ 21 октября 2010

Это ошибка в Firefox:

https://bugzilla.mozilla.org/show_bug.cgi?id=356558

Попробуйте этот обходной путь:

<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
28 голосов
/ 04 октября 2014

Я смог обойти эту ошибку, установив уникальный атрибут name в iframe - по какой-то причине это, похоже, разрушает кэш.Вы можете использовать любые динамические данные, которые у вас есть, в качестве атрибута name - или просто текущее время мс или нс на любом языке шаблонов, который вы используете.Это более хорошее решение, чем приведенное выше, поскольку оно не требует напрямую JS.

В моем конкретном случае iframe создается с помощью JS (но вы можете сделать то же самое с помощью PHP, Ruby и т. Д.)Я просто использую Date.now():

return '<iframe src="' + src + '" name="' + Date.now() + '" />';

Это исправляет ошибку в моем тестировании;вероятно, потому что window.name во внутреннем окне изменяется.

4 голосов
/ 26 сентября 2018

Как вы сказали, проблема здесь не в кэшировании содержимого iframe , а в кэшировании URL-адреса iframe .

По состоянию на сентябрь 2018 года, похоже, проблема все еще возникает в Chrome, но не в Firefox.

Я пробовал много вещей (добавление изменяющегося параметра GET, очистка URL-адреса iframe в onbeforeunload, обнаружение «перезагрузки из кэша» с использованием cookie, настройка различных заголовков ответов), и вот только два решения, которые работали с я:

1 - Простой способ: создать свой iframe динамически из JavaScript

Например:

const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl 
document.body.appendChild(iframe)

2- запутанный путь

На стороне сервера, как объяснено здесь , отключить кэширование контента для контента, который вы обслуживаете для iframe ИЛИ для родительской страницы (любой из них подойдет).

И

Установите URL-адрес iframe из javascript с дополнительным изменяющимся параметром поиска, например:

const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url

(упрощенная версия, остерегайтесь других параметров поиска)

3 голосов
/ 22 апреля 2015

Попробовав все остальное (кроме использования прокси для содержимого iframe), я нашел способ предотвратить кэширование содержимого iframe, из того же домена :

Используйте .htaccess и правило перезаписи и измените атрибут iframe src.

RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]

То, как я это использую, заключается в том, что URL-адрес iframe выглядит следующим образом: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Где [токен] - это случайно сгенерированное значение. Этот URL-адрес предотвращает кэширование iframe, поскольку токен никогда не совпадает, и iframe считает, что это совершенно другая веб-страница, поскольку при одном обновлении загружается совершенно другой URL-адрес:

example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html

оба ведут на одну и ту же страницу.

Вы можете получить доступ к параметрам скрытого URL с помощью $_SERVER["QUERY_STRING"]

3 голосов
/ 13 мая 2014

Чтобы iframe всегда загружал свежий контент, добавьте текущую временную метку Unix в конец параметров GET. Затем браузер воспринимает его как «другой» запрос и будет искать новый контент.

В Javascript это может выглядеть так:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
3 голосов
/ 23 марта 2011

Это ошибка в Firefox 3.5.

Посмотрите .. https://bugzilla.mozilla.org/show_bug.cgi?id=279048

2 голосов
/ 17 марта 2016

Я обнаружил эту проблему в последнем Chrome, а также в последнем Safari на Mac OS X по состоянию на 17 марта 2016 года. Ни одно из вышеперечисленных исправлений не помогло мне, включая назначение src пустым и затем возвращение на какой-то сайт или добавление какого-либо случайно названного параметра "name", или добавление случайного числа в конце URL-адреса после хэша, или назначение href окна содержимого для src после назначения src.

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

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

2 голосов
/ 18 апреля 2012

Я установил атрибут iframe src позже в моем приложении. Чтобы избавиться от кэшированного содержимого внутри iframe при запуске приложения, я просто делаю:

myIframe.src = "";

... где-то в начале кода js (например, в обработчике jquery $ ())

Благодаря http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/

0 голосов
/ 06 августа 2016

У меня тоже была эта проблема в 2016 году с iOS Safari. Казалось, что работа для меня была предоставление GET-параметра для iframe src и значения для него, как это <iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>

0 голосов
/ 07 октября 2010

Если вы хотите получить действительно сумасшедший, вы можете реализовать имя страницы в виде динамического URL, который всегда разрешается на одной странице, а не параметр строки запроса?

Предполагая, что вы находитесь в офисе, проверьте, происходит ли кэширование на уровне сети. Поверьте мне, это возможно. Ваши ИТ-специалисты смогут сообщить вам, есть ли какая-либо сетевая инфраструктура, связанная с кэшированием HTTP, хотя, поскольку это происходит только для iframe, это маловероятно.

...