如何阻止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
。
这是我到目前为止所尝试的内容:
我无法执行任何JavaScript技巧,因为我被同源策略阻止了。
我的想法已经不多了。有谁知道如何阻止浏览器缓存iframed内容?
我安装了Fiddler2,因为Daniel建议再进行一次测试,不幸的是,我仍然得到了相同的结果。
这是我进行的测试:
Math.random()
生成随机数。通过此测试,我能够确切地看到哪些页面正在更新,以及哪些页面被缓存。
要进行快速测试,我会加载页面,导航到另一个页面,然后按“返回”。结果如下:
原始页面:
离开页面,然后回击:
这表明内部页面正在被缓存,即使外部页面在URL中使用不同的GET参数调用它。出于某种原因,浏览器忽略了iframe请求新URL的事实;它只是加载旧的。
果然,Fiddler证实了同样的事情。
(我加载页面。)
调用外页。 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网址有任何想法?
答案 0 :(得分:46)
这是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>
答案 1 :(得分:28)
我已经能够通过在iframe上设置唯一的name
属性来解决此错误 - 无论出于何种原因,这似乎破坏了缓存。您可以使用您拥有的任何动态数据作为name
属性 - 或者只使用您正在使用的任何模板语言的当前ms或ns时间。这是一个比上面更好的解决方案,因为它不直接需要JS。
在我的特定情况下,iframe是通过JS构建的(但你可以通过PHP,Ruby等做同样的事情),所以我只使用Date.now()
:
return '<iframe src="' + src + '" name="' + Date.now() + '" />';
这修复了我测试中的错误;可能是因为内部窗口中的window.name
发生了变化。
答案 2 :(得分:4)
正如您所说,这里的问题不是 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-复杂的方式
如here所述,服务器端为您为父页面的iframe OR 提供的内容禁用了内容缓存(两者都可以)。
AND
通过javascript设置iframe网址以及其他更改的搜索参数,例如:
const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url
(简化版,请注意其他搜索参数)
答案 3 :(得分:3)
这是Firefox 3.5中的一个错误。
答案 4 :(得分:3)
要使iframe始终加载新内容,请将当前Unix时间戳添加到GET参数的末尾。然后,浏览器将其视为“不同”的浏览器。请求并寻求新的内容。
在Javascript中,它可能看起来像:
frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '×tamp=' + timestamp;
答案 5 :(得分:3)
在尝试其他所有内容后(除了使用iframe内容的代理),我找到了一种方法来阻止iframe内容缓存,来自同一个域:
使用.htaccess
和重写规则并更改iframe src
属性。
RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]
我使用它的方式是iframe的网址最终会这样:example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
其中[token]是随机生成的值。这个URL可以防止iframe缓存,因为令牌永远不会相同,而iframe认为它是一个完全不同的网页,因为单个刷新会加载一个完全不同的URL:
example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html
都会导致同一页面。
访问隐藏的网址参数答案 6 :(得分:2)
我稍后在我的应用中设置了iframe src属性。要在应用程序开始时删除iframe中的缓存内容,我只需执行以下操作:
myIframe.src = "";
...在js代码的开头某处(例如在jquery $()处理程序中)
谢谢 http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/
答案 7 :(得分:2)
我在2016年3月17日的最新Chrome以及Mac OS X上的最新Safari中发现了这个问题。上面没有任何修复程序适用于我,包括将src指定为空,然后返回某个网站,或者添加一些随机命名的“name”参数,或者在散列后的URL末尾添加一个随机数,或者在分配src后将内容窗口href分配给src。
在我的情况下,这是因为我使用Javascript来更新IFRAME,并且只在URL中切换哈希。
我的案例中的解决方法是我创建了一个临时URL,其中0秒元重定向到另一个页面。它发生得太快了,我几乎没有注意到屏幕闪烁。另外,我将临时页面的背景颜色设置为与其他页面相同,因此您更少注意到它。
答案 8 :(得分:0)
2016年,iOS Safari也遇到了这个问题。似乎对我有用的是
给iframe src一个GET参数和一个像这样的值
<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>
答案 9 :(得分:0)
我也遇到了这个问题,在尝试了不同的浏览器和大量的反复试验之后,我想出了这个解决方案,在我的情况下效果很好:
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' />
)
},
})
答案 10 :(得分:-1)
您安装了Fiddler2吗?
它可以让你准确地看到正在请求的内容,发回的内容等等。浏览器真正触及不同网址的缓存听起来似乎不合理。
答案 11 :(得分:-1)
将iframe的网址指向您网站上的网页,该网页充当代理,以检索并返回iframe的实际内容。现在您不再受同源策略的约束(编辑:不会阻止iframe缓存问题)。
答案 12 :(得分:-1)
您是否尝试将无缓存的各种HTTP标头选项添加到iframe页面?
答案 13 :(得分:-1)
如果您希望真的疯狂,您可以将页面名称实现为始终解析为同一页面的动态网址,而不是查询字符串选项?
假设您在办公室,请检查网络级别是否有任何缓存。相信我,这是一种可能性。您的IT人员将能够告诉您是否存在围绕HTTP缓存的任何网络基础架构,尽管这种情况仅发生在iframe上,因此不太可能。