Предотвращение кэширования 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?
Ответы
Ответ 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
во внутреннем окне.
Ответ 4
Это ошибка в Firefox 3.5.
Посмотрите..
https://bugzilla.mozilla.org/show_bug.cgi?id=279048
Ответ 5
Чтобы заставить iframe всегда загружать свежий контент, добавьте текущую временную метку Unix в конец параметров GET. Затем браузер видит его как "другой" запрос и будет искать новый контент.
В Javascript это может выглядеть так:
frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '×tamp=' + 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, это маловероятно.