Запобігання кешуванню iframe у браузері


86

Як запобігти 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 із випадковим значенням змінної
  • Додавання заголовків Expires, Cache-Control та Pragma до зовнішньої веб-сторінки
  • Додавання заголовків Expires, Cache-Control та Pragma до внутрішньої веб-сторінки

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

У мене закінчуються ідеї. Хтось знає, як перешкодити браузеру кешувати вміст із вбудованою рамкою?

Оновлення

Я встановив 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?


11
+1 - Ваш твір так красиво фіксує біль.
nickf

1
Дякую за дуже детальне пояснення проблеми, це на 100% саме те, що я відчуваю на сайті. Минуло сім років, а звіт про помилки firefox все ще присутній.
Скузі

Відповіді:


-3

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


41
це не заважає кешу.
baash05

@ baash05 Я ніколи не стверджував, що так; Я сказав, що це уникає політики того самого походження.
kmoser

1
Правда .. але в заголовку наголошується "Запобігання кешуванню iframe у браузері", і якщо ваша відповідь не перешкоджає кешуванню iframe у браузері, це насправді не відповідь. Це чудово знати, але все ж не є гарною порадою для тих, хто хоче запобігти кешуванню.
baash05

OP прагнув вирішити кешування та уникнути політики того самого походження. Часткова відповідь краще, ніж жодна :)
kmoser

2
тост завжди падає варенням боком вниз :)
baash05

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 років, і досі не встановлено.
kasukasz Zaroda

Це також стосується атрибута srcdoc, такого дивного ... Настільки чудовим, що я знайшов це.
elundmark

2
Я виявив цю саму проблему кешування з Chrome, і два рядки JavaScript вирішили її. Дякую!
Торн

2
Ого, була така сама проблема. Характерно для Firefox - чудово працював в IE, Chrome тощо. Дякую @caleb. Не можу повірити, що це тривало так довго.
Вуду,

32

Я зміг обійти цю помилку, встановивши унікальний nameатрибут у iframe - з якоїсь причини це, здається, руйнує кеш. Ви можете використовувати будь-які динамічні дані, які у вас є, як nameатрибут - або просто поточний час ms або ns будь-якою мовою шаблонів, яку ви використовуєте. Це більш приємне рішення, ніж наведені вище, оскільки воно безпосередньо не вимагає JS.

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

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

Це виправляє помилку під час мого тестування; можливо тому, що window.nameу внутрішньому вікні змінюється.


2
Ця відповідь працює для Chrome, Firefox та Safari станом на кінець 2015 р.
rovermicrover

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

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


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-секундне мета-перенаправлення на цю іншу сторінку. Це відбувається так швидко, що я майже не помічаю спалаху екрану. Крім того, я зробив колір фону проміжної сторінки таким же, як і на іншій сторінці, і тому ви помічаєте це ще менше.


2

Я встановив атрибут iframe src пізніше у своєму додатку. Щоб позбутися кешованого вмісту всередині iframe на початку програми, я просто роблю:

myIframe.src = "";

... десь на початку коду js (наприклад, у обробнику jquery $ ())

Завдяки http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/


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

Ви пробували додавати різні параметри заголовка HTTP для no-cache на сторінку iframe?


Так. Я спробував директиви no-cache як у заголовках HTTP, так і в метатегах на кожній сторінці.
JR.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.