浏览器中防止 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变量总是变化的。虽然 iframe 的 URL 已经更改(因此,浏览器应该对该页面发出新的请求) ,但是浏览器只获取缓存的内容。

我来回检查了 HTTP 请求和响应,发现即使外部页面包含 <iframe src="webpage2.html?var=222" />,浏览器仍然会获取 webpage2.html?var=111

以下是我目前为止的尝试:

  • 使用随机变量值更改 iframe URL
  • 在外部网页添加过期、缓存控制和 Pragma 头
  • 向内部网页添加过期、缓存控制和 Pragma 头

我无法使用任何 JavaScript 技巧,因为我被同源策略阻塞了。

我想不出办法了。有人知道怎么阻止浏览器缓存 ifraed 内容吗?

更新

我按照 Daniel 的建议安装了 Fiddler2来执行另一个测试,不幸的是,我仍然得到相同的结果。

这是我做的测试:

  1. 外页使用 JSP 中的 Math.random()生成随机数。
  2. 外页在网页上显示一个随机数字。
  3. 外部页面调用 iframe,传入一个随机数。
  4. 内页显示一个随机数。

通过这个测试,我能够准确地看到哪些页面正在更新,哪些页面被缓存。

视觉测试

为了进行快速测试,我加载这个页面,导航到另一个页面,然后按“返回”:

原页:

  • 外页: 0.21300034290246206
  • 内页: 0.21300034290246206

离开页面,然后反击:

  • 外页: 0.4470929019483644
  • 内页: 0.21300034290246206

这表明正在缓存内部页面,即使外部页面使用 URL 中的另一个 GET 参数调用它。由于某种原因,浏览器忽略了 iframe 正在请求新 URL 的事实; 它只是加载旧 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被称为。

从这个测试来看,网页浏览器似乎没有缓存页面,但是它缓存了 iframe 的 URL,然后对缓存的 URL 发出一个新的请求。然而,我仍然不知道如何解决这个问题。

有人知道如何阻止浏览器缓存 iframe URL 吗?

127783 次浏览

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.

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).

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.

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>

It is a bug in Firefox 3.5.

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

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/

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;

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.

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

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.

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>

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)

I also met this issue, after trying different browsers, and a ton of trial and error, I came up with this solution, which works well in my case:

import { defineComponent } from 'vue'
import { v4 as uuid } from 'uuid'


export default defineComponent({
setup() {
return () => (
// append a uuid after `?` to prevent browsers from caching it
<iframe src={`https://www.example.com?${uuid()}`} frameborder='0' />
)
},
})