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

86

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

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

Скрипач Тест

Конечно, 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?

JR.
источник
11
+1 - Ваше письмо так хорошо передает боль.
nickf
1
Спасибо за очень подробное объяснение проблемы, это на 100% именно то, что я испытываю на сайте. Прошло семь лет, а отчет об ошибке firefox все еще присутствует.
Scuzzy

Ответы:

-3

Сделайте так, чтобы URL-адрес iframe указывал на страницу вашего сайта, которая действует как прокси-сервер для получения и возврата фактического содержимого iframe. Теперь вы больше не связаны политикой одного и того же происхождения (EDIT: не предотвращает проблему кеширования iframe).

Kmoser
источник
41
это не мешает кешированию.
baash05 05
@ baash05 Я никогда не утверждал, что это так; Я сказал, что он избегает политики одного происхождения.
kmoser
1
Верно ... но заголовок операции гласит: «Предотвращение кеширования iframe в браузере», и если ваш ответ не предотвращает кеширование iframe в браузере, это не совсем ответ. Это полезно знать, но все же не лучший совет для тех, кто хочет предотвратить кеширование.
baash05 01
OP стремился решить проблему кеширования и избежать политики одного и того же происхождения. Частичный ответ лучше, чем ничего :)
kmoser
2
тост всегда падает вареньем вниз :)
baash05 05
58

Это ошибка в 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
Сегодня, 27.2.2014, я так счастлив, что нашел эту ветку, я подумал, что ее можно решить с помощью без кеширования на стороне сервера. FF 27 все еще имеет эту ошибку.
Роберт
7
7.8.2014 - 8 лет спустя, и все еще не исправлено.
Лукаш Зарода 07
Это также относится к атрибуту srcdoc, так странно ... Так здорово, что я нашел это.
elundmark 07
2
Я обнаружил ту же проблему с кешированием в Chrome, и две строки JavaScript решили ее. Спасибо!
Thorn
2
Вау, была точно такая же проблема. Конкретно для Firefox - отлично работал в IE, Chrome и т.д. Спасибо @caleb. Не могу поверить, что это длилось так долго.
Voodoo
32

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

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

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

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

STRML
источник
2
Этот ответ работает для Chrome, Firefox и Safari по состоянию на конец 2015 года.
rovermicrover, 01
13

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

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

steph643
источник
5

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

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

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"]

Джефф Ноэль
источник
1
Сработало у меня - спасибо!
Куинн Финни
@QuinnFinney Рад, что это было полезно кому-то еще. На решение этой проблемы у меня ушло несколько дней :)
Джефф Ноэль
Да, я тоже! хахаха
Куинн Финни
3

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

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

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
Шестой Дивизион
источник
3

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

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

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

Volomike
источник
2

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

myIframe.src = "";

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

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

Janekw
источник
0

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

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

Лаури Кяэрияйнен
источник
-1

Вы установили Fiddler2 ?

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

Дэниел Эрвикер
источник
1
Спасибо за подсказку по Fiddler2. Теперь я знаю, что браузер не кэширует содержимое iframe; он просто кеширует URL-адрес iframe. Однако я все еще в тупике и понятия не имею, почему браузер игнорирует URL-адрес iframe новой страницы и просто использует старый URL-адрес.
JR.
-1

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

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

Крис Уэбб
источник
-2

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

Крис Уэбб
источник
Ага. Я пробовал использовать директивы без кеширования как в заголовках HTTP, так и в метатегах на каждой странице.
JR.