防止浏览器中的iframe缓存


86

如何防止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

到目前为止,这是我尝试过的方法:

  • 使用随机var值更改iframe网址
  • 将Expires,Cache-Control和Pragma标头添加到外部网页
  • 将Expires,Cache-Control和Pragma标头添加到内部网页

我无法执行任何JavaScript技巧,因为我被同源政策所阻止。

我的想法不多了。有谁知道如何阻止浏览器缓存iframed内容?

更新资料

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

这是我执行的测试:

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

通过此测试,我可以准确地看到哪些页面正在更新以及哪些页面已缓存。

外观测试

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

原始页面:

  • 外页:0.21300034290246206
  • 内页:0.21300034290246206

离开页面,然后回击:

  • 外页:0.4470929019483644
  • 内页:0.21300034290246206

这表明即使外部页面使用URL中的其他GET参数调用内部页面,也正在缓存内部页面。由于某种原因,浏览器会忽略iframe正在请求新网址的事实;它只是加载旧的。

提琴手测试

果然,提琴手证实了同一件事。

(我加载页面。)

称为外页。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

好吧,从此测试来看,似乎Web浏览器未在缓存页面,而是在缓存iframe的URL,然后对该缓存的URL发出新请求。但是,我仍然对如何解决此问题感到困惑。

是否有人对如何停止网络浏览器缓存iframe网址有任何想法?


11
+1-您的作品很好地抓住了痛苦。
尼克

1
感谢您对问题的详细说明,这完全是我在一个网站上遇到的100%的错误。已经七年了,firefox错误报告仍然存在。
令人作呕的

Answers:


-3

使iframe的URL指向您网站上的页面,该页面充当检索和返回iframe实际内容的代理。现在,您不再受同源策略的约束(编辑:不会阻止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年后,仍未修复。
卢卡斯Zaroda

这也适用于srcdoc属性,太奇怪了。。。
elundmark 2014年

2
我发现Chrome具有相同的缓存问题,而JavaScript的两行代码解决了该问题。谢谢!
索恩

2
哇,有完全一样的问题。是特定于Firefox的-在IE,Chrome等系统中运行良好。感谢@caleb。不能相信这已经持续了很长时间。
Voodoo

32

通过name在iframe上设置唯一属性,我已经能够解决此错误-无论出于何种原因,这似乎都会破坏缓存。您可以将任何动态数据用作name属性,也可以仅使用当前使用的模板语言来显示当前的ms或ns时间。这是比上面的解决方案更好的解决方案,因为它不需要直接使用JS。

在我的特定情况下,iframe是通过JS构建的(但是您可以通过PHP,Ruby进行任何操作),因此我只需使用Date.now()

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

这修复了我测试中的错误;可能是因为window.name内部窗口中的变化。


2
截至2015年末,此答案适用于Chrome,Firefox和
Safari。– rovermicrover

13

如您所说,这里的问题不是iframe内容缓存,而是iframe网址缓存

截至2018年9月,似乎该问题仍在Chrome中出现,但在Firefox中未出现。

我尝试了很多事情(添加更改的GET参数,清除onbeforeunload中的iframe网址,使用Cookie检测“从缓存中重新加载”,设置各种响应标头),这是我唯一有效的两种解决方案:

1-简单的方法:从javascript动态创建iframe

例如:

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

2-复杂的方式

服务器端,如解释在这里,禁用内容缓存为您服务为iframe的内容父页面(或者也可以)。

设置来自javascript的iframe网址以及其他更改的搜索参数,如下所示:

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

(简化版,请注意其他搜索参数)


5

尝试了所有其他方法(使用iframe内容的代理除外)之后,我发现了一种防止来自同一域的iframe内容缓存的方法:

使用.htaccess和重写规则并更改iframesrc属性。

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

我使用这种方式的方式是,iframe的网址最终看起来是这样的: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

其中[令牌]是随机生成的值。该URL阻止了iframe缓存,因为令牌从未相同,并且iframe认为它是一个完全不同的网页,因为一次刷新加载了一个完全不同的URL:

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

两者都指向同一页面。

您可以使用以下命令访问隐藏的网址参数 $_SERVER["QUERY_STRING"]


1
为我工作-谢谢!
奎因·芬尼

@QuinnFinney很高兴这对其他人很有用。这个问题花了我几天时间才能解决:)
Jeff Noel

我也是!哈哈哈
奎因·芬尼


3

要使iframe始终加载新内容,请将当前Unix时间戳添加到GET参数的末尾。然后,浏览器将其视为“不同的”请求,并将寻求新的内容。

在Javascript中,它可能类似于:

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

3

截至2016年3月17日,我在最新的Chrome浏览器和Mac OS X上的最新Safari中发现了此问题。上述修复均无济于事,包括将src分配为空然后再返回到某些站点,或添加一些随机命名的“名称”参数,或者在哈希之后的URL末尾添加一个随机数,或者在分配src之后将内容窗口href分配给src。

就我而言,这是因为我使用Javascript更新了IFRAME,并且仅切换了URL中的哈希值。

在我的情况下,解决方法是我创建了一个临时URL,该URL具有0秒的元重定向到该其他页面。它发生得如此之快,以至于我几乎没有注意到屏幕闪烁。另外,我将过渡页的背景颜色设置为与其他页面相同,因此您注意到的颜色更少。



0

我在2016年的iOS Safari中也遇到了这个问题。似乎对我有用的是为iframe src提供一个GET参数,并为其指定一个值

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


-1

您安装了Fiddler2吗?

它可以让您确切地看到所请求的内容,发回的内容等。浏览器为不同的URL真正访问其缓存似乎并不合理。


1
感谢Fiddler2的提示。现在,我知道浏览器未在缓存iframe内容;它只是缓存iframe网址。但是,我仍然很困惑,我也不知道为什么浏览器会忽略新页面的iframe URL,而只是使用旧的URL。
JR。

-1

如果你真的想要疯狂,你可以实现网页的名称为动态URL总是解析到同一页面,而不是查询字符串的选择吗?

假设您在办公室中,请检查是否在网络级别进行了任何缓存。相信我,这是有可能的。您的IT人员将能够告诉您HTTP缓存周围是否有任何网络基础架构,尽管由于这仅发生在iframe中,所以可能性很小。


-2

您是否尝试过将各种用于非缓存的HTTP标头选项添加到iframe页面?


对。我在每个页面的HTTP标头和meta标签中都尝试了no-cache指令。
JR。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.