Mencegah cache iframe di browser

88

Bagaimana Anda mencegah Firefox dan Safari menyimpan konten iframe dalam cache?

Saya memiliki halaman web sederhana dengan iframe ke halaman di situs lain. Baik halaman luar maupun dalam memiliki header respons HTTP untuk mencegah penyimpanan dalam cache. Ketika saya mengklik tombol "kembali" di browser, halaman luar berfungsi dengan baik, tetapi apa pun yang terjadi, browser selalu mengambil cache dari halaman ifram. IE berfungsi dengan baik, tetapi Firefox dan Safari memberi saya masalah.

Halaman web saya terlihat seperti ini:

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

The varvariabel selalu berubah. Terlepas dari kenyataan bahwa URL iframe telah berubah (dan karenanya, browser harus membuat permintaan baru ke halaman itu), browser hanya mengambil konten yang di-cache.

Saya telah memeriksa permintaan dan respons HTTP bolak-balik, dan saya perhatikan bahwa meskipun halaman luarnya berisi <iframe src="webpage2.html?var=222" />, browser masih akan mengambil webpage2.html?var=111.

Inilah yang saya coba sejauh ini:

  • Mengubah URL iframe dengan nilai var acak
  • Menambahkan header Expires, Cache-Control, dan Pragma ke halaman web luar
  • Menambahkan header Expires, Cache-Control, dan Pragma ke halaman dalam

Saya tidak dapat melakukan trik JavaScript apa pun karena saya diblokir oleh kebijakan asal yang sama.

Saya kehabisan ide. Adakah yang tahu cara menghentikan browser agar tidak menyimpan konten iframed?

Memperbarui

Saya menginstal Fiddler2 seperti yang disarankan Daniel untuk melakukan tes lain, dan sayangnya, saya masih mendapatkan hasil yang sama.

Ini adalah tes yang saya lakukan:

  1. Halaman luar menghasilkan nomor acak menggunakan Math.random()JSP.
  2. Halaman luar menampilkan nomor acak di halaman web.
  3. Halaman luar memanggil iframe, meneruskan nomor acak.
  4. Halaman dalam menampilkan nomor acak.

Dengan pengujian ini, saya dapat melihat dengan tepat halaman mana yang diperbarui, dan halaman mana yang di-cache.

Tes Visual

Untuk tes cepat, saya memuat halaman, menavigasi ke halaman lain, dan kemudian tekan "kembali." Berikut hasilnya:

Halaman Asli:

  • Halaman Luar: 0,21300034290246206
  • Halaman Dalam: 0,21300034290246206

Meninggalkan halaman, lalu menekan kembali:

  • Halaman luar: 0.4470929019483644
  • Halaman dalam: 0,21300034290246206

Ini menunjukkan bahwa halaman dalam sedang di-cache, meskipun halaman luar memanggilnya dengan parameter GET yang berbeda di URL. Untuk beberapa alasan, browser mengabaikan fakta bahwa iframe meminta URL baru; itu hanya memuat yang lama.

Uji Fiddler

Benar saja, Fiddler menegaskan hal yang sama.

(Saya memuat halaman.)

Halaman luar disebut. HTML:

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

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 dipanggil.

(Saya menavigasi keluar dari halaman dan kemudian membalas.)

Halaman luar disebut. HTML:

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

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 dipanggil.

Nah, dari pengujian ini, tampaknya browser web tidak sedang menyimpan halaman, tetapi menyimpan URL iframe dan kemudian membuat permintaan baru pada URL yang di-cache tersebut. Namun, saya masih bingung bagaimana mengatasi masalah ini.

Adakah yang punya ide tentang cara menghentikan browser web dari cache URL iframe?

JR.
sumber
11
+1 - Tulisan Anda menangkap rasa sakit dengan sangat baik.
nickf
1
Terima kasih atas penjelasan masalahnya yang sangat detail, ini 100% persis seperti yang saya alami dengan sebuah situs. Sudah tujuh tahun dan laporan bug firefox masih ada.
Scuzzy

Jawaban:

-3

Jadikan URL iframe mengarah ke halaman di situs Anda yang bertindak sebagai proxy untuk mengambil dan mengembalikan konten iframe yang sebenarnya. Sekarang Anda tidak lagi terikat oleh kebijakan asal yang sama (EDIT: tidak mencegah masalah cache iframe).

kmoser
sumber
41
ini tidak mencegah cache.
baash05
@ baash05 Saya tidak pernah mengklaimnya; Saya mengatakan itu menghindari kebijakan asal yang sama.
kmoser
1
Benar .. tetapi judul opnya berbunyi "Mencegah cache iframe di browser" dan jika jawaban Anda tidak mencegah cache iframe di browser, itu sebenarnya bukan jawaban. Ini bagus untuk diketahui, tetapi tetap bukan saran yang baik untuk seseorang yang ingin mencegah penyimpanan ke cache.
baash05
OP sedang mencari untuk menyelesaikan caching dan menghindari kebijakan yang sama-asal. Jawaban parsial lebih baik daripada tidak sama sekali :)
kmoser
2
roti panggang selalu jatuh di sisi selai :)
baash05
59

Ini adalah bug di Firefox:

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

Coba solusi ini:

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

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
Caleb
sumber
3
Hari ini 27.2.2014 Saya sangat senang menemukan utas ini, saya pikir ini dapat diselesaikan dengan sisi server tanpa caching. FF 27 masih memiliki bug ini.
Robert
7
7.8.2014 - 8 tahun kemudian, dan masih belum diperbaiki.
Łukasz Zaroda
Ini juga berlaku untuk atribut srcdoc, sangat aneh ... Terima kasih sekali saya menemukan ini.
elundmark
2
Saya menemukan masalah cache yang sama dengan Chrome dan dua baris JavaScript menyelesaikannya. Terima kasih!
Thorn
2
Wah, punya masalah yang sama persis. Khusus untuk Firefox - berfungsi dengan baik di IE, Chrome, dll. Terima kasih @caleb. Tidak percaya ini telah bertahan lama.
Voodoo
33

Saya telah dapat mengatasi bug ini dengan menetapkan nameatribut unik pada iframe - untuk alasan apa pun, ini tampaknya merusak cache. Anda dapat menggunakan data dinamis apa pun yang Anda miliki sebagai filename atribut - atau hanya waktu ms atau ns saat ini dalam bahasa template apa pun yang Anda gunakan. Ini adalah solusi yang lebih bagus daripada yang di atas karena tidak secara langsung membutuhkan JS.

Dalam kasus khusus saya, iframe sedang dibangun melalui JS (tetapi Anda dapat melakukan hal yang sama melalui PHP, Ruby, apa pun), jadi saya cukup menggunakan Date.now():

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

Ini memperbaiki bug dalam pengujian saya; mungkin karena window.namedi jendela bagian dalam berubah.

STRML
sumber
2
Jawaban ini berfungsi untuk Chrome, Firefox, dan Safari pada akhir 2015.
rovermicrover
13

Seperti yang Anda katakan, masalahnya di sini bukanlah cache konten iframe , tetapi cache url iframe .

Mulai September 2018, tampaknya masalah tersebut masih terjadi di Chrome tetapi tidak di Firefox.

Saya telah mencoba banyak hal (menambahkan parameter GET yang berubah, menghapus url iframe di onbeforeunload, mendeteksi "muat ulang dari cache" menggunakan cookie, menyiapkan berbagai header respons) dan berikut adalah dua solusi yang berhasil dari saya:

1- Cara mudah: buat iframe Anda secara dinamis dari javascript

Sebagai contoh:

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

2- Cara berbelit-belit

Sisi server, seperti dijelaskan di sini , nonaktifkan cache konten untuk konten yang Anda sajikan untuk iframe ATAU untuk halaman induk (keduanya akan dilakukan).

DAN

Setel url iframe dari javascript dengan parameter pencarian tambahan yang berubah, seperti ini:

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

(versi sederhana, waspadalah terhadap parameter pencarian lainnya)

steph643
sumber
5

Setelah mencoba yang lainnya (kecuali menggunakan proxy untuk konten iframe), saya menemukan cara untuk mencegah cache konten iframe, dari domain yang sama :

Gunakan .htaccessdan tulis ulang aturan dan ubah srcatribut iframe .

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

Cara saya menggunakan ini adalah bahwa URL iframe akhirnya terlihat seperti ini: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Di mana [token] adalah nilai yang dihasilkan secara acak. URL ini mencegah cache iframe karena tokennya tidak pernah sama, dan iframe menganggapnya sebagai halaman web yang sama sekali berbeda karena satu penyegaran memuat URL yang sama sekali berbeda:

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

keduanya mengarah ke halaman yang sama.

Anda dapat mengakses parameter url tersembunyi Anda dengan $_SERVER["QUERY_STRING"]

Jeff Noel
sumber
1
Bekerja untuk saya - Terima kasih!
Quinn Finney
@QuinnFinney Senang ini berguna untuk orang lain. Masalah ini butuh waktu beberapa hari untuk saya pecahkan :)
Jeff Noel
Ya saya juga! hahaha
Quinn Finney
3

Agar iframe selalu memuat konten baru, tambahkan stempel waktu Unix saat ini ke akhir parameter GET. Browser kemudian melihatnya sebagai permintaan 'berbeda' dan akan mencari konten baru.

Dalam Javascript, mungkin terlihat seperti ini:

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

Saya menemukan masalah ini di Chrome terbaru serta Safari terbaru di Mac OS X mulai 17 Maret 2016. Tidak ada perbaikan di atas yang berhasil untuk saya, termasuk menetapkan src ke kosong dan kemudian kembali ke beberapa situs, atau menambahkan beberapa parameter "nama" yang diberi nama secara acak, atau menambahkan nomor acak di akhir URL setelah hash, atau menetapkan href jendela konten ke src setelah menetapkan src.

Dalam kasus saya, itu karena saya menggunakan Javascript untuk memperbarui IFRAME, dan hanya mengganti hash di URL.

Solusi dalam kasus saya adalah saya membuat URL sementara yang memiliki pengalihan meta 0 detik ke halaman lain tersebut. Itu terjadi sangat cepat sehingga saya hampir tidak memperhatikan layar berkedip. Selain itu, saya membuat warna latar belakang halaman sementara sama dengan halaman lainnya, sehingga Anda bahkan kurang menyadarinya.

Volomike
sumber
0

Saya juga mengalami masalah ini pada tahun 2016 dengan iOS Safari. Apa yang tampaknya berhasil bagi saya adalah memberikan parameter GET ke iframe src dan nilainya seperti ini

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

Lauri Kääriäinen
sumber
-1

Sudahkah Anda menginstal Fiddler2 ?

Ini akan membiarkan Anda melihat dengan tepat apa yang diminta, apa yang dikirim kembali, dll. Kedengarannya tidak masuk akal bahwa browser akan benar-benar menekan cache untuk URL yang berbeda.

Daniel Earwicker
sumber
1
Terima kasih atas tipnya tentang Fiddler2. Sekarang saya tahu bahwa browser tidak menyimpan konten iframe dalam cache; itu hanya menyimpan URL iframe. Namun, saya masih bingung, dan saya tidak tahu mengapa browser mengabaikan URL iframe dari halaman baru dan hanya menggunakan URL lama.
JR.
-1

Jika Anda ingin benar-benar gila, Anda dapat menerapkan nama halaman sebagai url dinamis yang selalu memutuskan ke halaman yang sama, bukan opsi querystring?

Dengan asumsi Anda berada di kantor, periksa apakah ada cache yang terjadi di tingkat jaringan. Percayalah, itu kemungkinan. Orang-orang IT Anda akan dapat memberi tahu Anda jika ada infrastruktur jaringan di sekitar caching HTTP, meskipun ini hanya terjadi untuk iframe, itu tidak mungkin.

Chris Webb
sumber
-2

Sudahkah Anda mencoba menambahkan berbagai opsi HTTP Header untuk no-cache ke halaman iframe?

Chris Webb
sumber
Ya. Saya sudah mencoba perintah tanpa-cache di header HTTP dan tag meta di setiap halaman.
JR.