Подтвердить что ты не робот

Предотвращение кэширования iframe в браузере

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

У меня есть простая веб-страница с iframe на странице на другом сайте. На внешней странице и на внутренней странице есть заголовки HTTP-ответов, чтобы предотвратить кеширование. Когда я нажимаю кнопку "Назад" в браузере, внешняя страница работает правильно, но независимо от того, браузер всегда извлекает кеш страницы iframed. 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?

Update

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

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

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

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

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

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

Оригинальная страница:

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

Закройте страницу, затем нажмите:

  • Внешняя страница: 0.4470929019483644
  • Внутренняя страница: 0.21300034290246206

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

Тест Fiddler

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

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

Вызывается внешняя страница. 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?

4b9b3361

Ответ 1

Сделайте так, чтобы URL-адрес iframe указывал на страницу на вашем сайте, которая выступает в качестве прокси-сервера для извлечения и возврата фактического содержимого iframe. Теперь вы больше не связаны политикой того же происхождения (РЕДАКТИРОВАТЬ: не предотвращает проблему кэширования iframe).

Ответ 2

Это ошибка в 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>

Ответ 3

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

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

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

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

Ответ 5

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

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

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;

Ответ 6

После пробовать все остальное (за исключением использования прокси для содержимого 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"]

Ответ 7

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

myIframe.src = "";

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

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

Ответ 8

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

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

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

Ответ 9

Как вы сказали, проблема здесь не в кэшировании контента 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

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

Ответ 10

У меня также была эта проблема в 2016 году с iOS Safari. То, что, казалось, работало для меня, было давая параметр GET для iframe src и значение для него вроде этого

<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>

Ответ 11

Установили ли вы Fiddler2?

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

Ответ 12

Вы пытались добавить различные параметры заголовка HTTP для отсутствия кеша на страницу iframe?

Ответ 13

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

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