91

How do you prevent Firefox and Safari from caching iframe content?

I have a simple webpage with an iframe to a page on a different site. Both the outer page and the inner page have HTTP response headers to prevent caching. When I click the "back" button in the browser, the outer page works properly, but no matter what, the browser always retrieves a cache of the iframed page. IE works just fine, but Firefox and Safari are giving me trouble.

My webpage looks something like this:

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

The var variable always changes. Despite the fact that the URL of the iframe has changed (and thus, the browser should be making a new request to that page), the browser just fetches the cached content.

I've examined the HTTP requests and responses going back and forth, and I noticed that even if the outer page contains <iframe src="webpage2.html?var=222" />, the browser will still fetch webpage2.html?var=111.

Here's what I've tried so far:

  • Changing iframe URL with random var value
  • Adding Expires, Cache-Control, and Pragma headers to outer webpage
  • Adding Expires, Cache-Control, and Pragma headers to inner webpage

I'm unable to do any JavaScript tricks because I'm blocked by the same-origin policy.

I'm running out of ideas. Does anyone know how to stop the browser from caching the iframed content?

Update

I installed Fiddler2 as Daniel suggested to perform another test, and unfortunately, I am still getting the same results.

This is the test I performed:

  1. Outer page generates random number using Math.random() in JSP.
  2. Outer page displays random number on webpage.
  3. Outer page calls iframe, passing in random number.
  4. Inner page displays random number.

With this test, I'm able to see exactly which pages are updating, and which pages are cached.

Visual Test

For a quick test, I load the page, navigate to another page, and then press "back." Here are the results:

Original Page:

  • Outer Page: 0.21300034290246206
  • Inner Page: 0.21300034290246206

Leaving page, then hitting back:

  • Outer page: 0.4470929019483644
  • Inner page: 0.21300034290246206

This shows that the inner page is being cached, even though the outer page is calling it with a different GET parameter in the URL. For some reason, the browser is ignoring the fact that the iframe is requesting a new URL; it simply loads the old one.

Fiddler Test

Sure enough, Fiddler confirms the same thing.

(I load the page.)

Outer page is called. HTML:

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

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

(I navigate away from the page and then hit back.)

Outer page is called. HTML:

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

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

Well, from this test, it looks as though the web browser isn't caching the page, but it's caching the URL of the iframe and then making a new request on that cached URL. However, I'm still stumped as to how to solve this issue.

Does anyone have any ideas on how to stop the web browser from caching iframe URLs?

JR.
  • 5,320
  • 8
  • 29
  • 33
  • 11
    +1 -- Your writing captures the pain so nicely. – nickf Mar 26 '12 at 21:05
  • 1
    Thank you for the very detailed explanation of the problem, this is 100% exactly what I am experiencing with a site. It's been seven years and the [firefox bug report](https://bugzilla.mozilla.org/show_bug.cgi?id=356558) is still present. – Scuzzy May 11 '17 at 10:11

13 Answers13

61

This is a bug in Firefox:

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

Try this workaround:

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

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
Caleb
  • 2,023
  • 1
  • 19
  • 21
  • 3
    Today 27.2.2014 I am so happy to found this thread, I thought it could be solved by server side no-caching. FF 27 still have this bug. – Robert Feb 27 '14 at 15:27
  • 8
    7.8.2014 - 8 years later, and still not fixed. – Łukasz Zaroda Aug 07 '14 at 11:01
  • This also applies to the srcdoc attribute, so strange... So greatful I found this. – elundmark Nov 07 '14 at 19:57
  • 2
    I found this same caching problem with Chrome and the two lines of JavaScript resolved it. Thank you! – Thorn Dec 03 '14 at 00:02
  • 2
    Wow, had the exact same problem. Was specific to Firefox - worked fine in IE, Chrome, etc. Thanks @caleb. Can't believe this has lingered so long. – Voodoo Dec 18 '14 at 19:55
  • Actually having a similar problem with Chrome and google maps in an iframe that was being written via javascript. This fixed it as well. – Eric Brandel Jul 01 '15 at 20:03
  • I tried the workaround above, and while it does work properly for fixed content, it makes the frame ignore all links passed to it. So, if you have a menu with a bunch of links going into this frame, something is missing. What is then wrong? – Ingemar Ragnemalm Sep 15 '15 at 02:34
35

I have been able to work around this bug by setting a unique name attribute on the iframe - for whatever reason, this seems to bust the cache. You can use whatever dynamic data you have as the name attribute - or simply the current ms or ns time in whatever templating language you're using. This is a nicer solution than those above because it does not directly require JS.

In my particular case, the iframe is being built via JS (but you could do the same via PHP, Ruby, whatever), so I simply use Date.now():

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

This fixes the bug in my testing; probably because the window.name in the inner window changes.

STRML
  • 762
  • 10
  • 7
15

As you said, the issue here is not iframe content caching, but iframe url caching.

As of September 2018, it seems the issue still occurs in Chrome but not in Firefox.

I've tried many things (adding a changing GET parameter, clearing the iframe url in onbeforeunload, detecting a "reload from cache" using a cookie, setting up various response headers) and here are the only two solutions that worked from me:

1- Easy way: create your iframe dynamically from javascript

For example:

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

2- Convoluted way

Server-side, as explained here, disable content caching for the content you serve for the iframe OR for the parent page (either will do).

AND

Set the iframe url from javascript with an additional changing search param, like this:

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

(simplified version, beware of other search params)

steph643
  • 2,045
  • 1
  • 18
  • 17
5

After trying everything else (except using a proxy for the iframe content), I found a way to prevent iframe content caching, from the same domain:

Use .htaccess and a rewrite rule and change the iframe src attribute.

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

The way I use this is that the iframe's URL end up looking this way: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Where [token] is a randomly generated value. This URL prevents iframe caching since the token is never the same, and the iframe thinks it's a totally different webpage since a single refresh loads a totally different URL :

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

both lead to the same page.

You can access your hidden url parameters with $_SERVER["QUERY_STRING"]

Jeff Noel
  • 6,972
  • 3
  • 35
  • 63
4

I found this problem in the latest Chrome as well as the latest Safari on the Mac OS X as of Mar 17, 2016. None of the fixes above worked for me, including assigning src to empty and then back to some site, or adding in some randomly-named "name" parameter, or adding in a random number on the end of the URL after the hash, or assigning the content window href to the src after assigning the src.

In my case, it was because I was using Javascript to update the IFRAME, and only switching the hash in the URL.

The workaround in my case was that I created an interim URL that had a 0 second meta redirect to that other page. It happens so fast that I hardly notice the screen flash. Plus, I made the background color of the interim page the same as the other page, and so you notice it even less.

Volomike
  • 21,378
  • 19
  • 99
  • 188
3

To get the iframe to always load fresh content, add the current Unix timestamp to the end of the GET parameters. The browser then sees it as a 'different' request and will seek new content.

In Javascript, it might look like:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
Division Six
  • 166
  • 6
3

It is a bug in Firefox 3.5.

Have a look.. https://bugzilla.mozilla.org/show_bug.cgi?id=279048

renga
  • 31
  • 1
2

I set iframe src attribute later in my app. To get rid of the cached content inside iframe at the start of the application I simply do:

myIframe.src = "";

... somewhere in the beginning of js code (for instance in jquery $() handler)

Thanks to http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/

janekw
  • 86
  • 5
0

I also had this problem in 2016 with iOS Safari. What seemed to work for me was giving a GET-parameter to the iframe src and a value for it like this

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

-1

If you want to get really crazy you could implement the page name as a dynamic url that always resolves to the same page, rather than the querystring option?

Assuming you're in an office, check whether there's any caching going on at a network level. Believe me, it's a possibility. Your IT folks will be able to tell you if there's any network infrastructure around HTTP caching, although since this only happens for the iframe it's unlikely.

Chris Webb
  • 668
  • 6
  • 20
-2

Have you installed Fiddler2?

It will let you see exactly what is being requested, what is being sent back, etc. It doesn't sound plausible that the browser would really hit its cache for different URLs.

Daniel Earwicker
  • 108,589
  • 35
  • 194
  • 274
  • 1
    Thanks for the tip on Fiddler2. Now I know that the browser isn't caching the iframe content; it's simply caching the iframe URL. However, I'm still stumped, and I have no idea why the browser would ignore the iframe URL of the new page and simply just use the old URL. – JR. Apr 15 '10 at 21:19
-2

Have you tried adding the various HTTP Header options for no-cache to the iframe page?

Chris Webb
  • 668
  • 6
  • 20
  • Yup. I've tried no-cache directives in both the HTTP headers and the meta tags on each page. – JR. Oct 06 '10 at 14:46
-4

Make the URL of the iframe point to a page on your site which acts as a proxy to retrieve and return the actual contents of the iframe. Now you are no longer bound by the same-origin policy (EDIT: does not prevent the iframe caching issue).

kmoser
  • 5,337
  • 2
  • 18
  • 30
  • 41
    this does not prevent the cache. – baash05 Dec 05 '12 at 00:45
  • @baash05 I never claimed it did; I said it avoids the same-origin policy. – kmoser Nov 29 '18 at 06:09
  • 1
    True.. but the op title reads "Preventing iframe caching in browser" and if your answer does not prevent iframe caching in the browser, it's not really an answer. It's neat to know, but still not good advice for someone looking to prevent caching. – baash05 Dec 01 '18 at 06:21
  • OP was looking to solve caching *and* avoid the same-origin policy. A partial answer is better than none :) – kmoser Dec 04 '18 at 05:01
  • 2
    toast always falls jam side down :) – baash05 Dec 05 '18 at 06:48