防止在浏览器中使用iframe缓存

时间:2010-04-15 18:40:11

标签: browser caching iframe back-button

如何阻止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网址
  • 将Expires,Cache-Control和Pragma标题添加到外部网页
  • 将Expires,Cache-Control和Pragma标头添加到内部网页

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

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

更新

我安装了Fiddler2,因为Daniel建议再进行一次测试,不幸的是,我仍然得到了相同的结果。

这是我进行的测试:

  1. 外页使用JSP中的Math.random()生成随机数。
  2. 外页在网页上显示随机数。
  3. 外页调用iframe,传入随机数。
  4. 内页显示随机数。
  5. 通过此测试,我能够确切地看到哪些页面正在更新,以及哪些页面被缓存。

    视觉测试

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

    原始页面:

    • 外页:0.21300034290246206
    • 内页:0.21300034290246206

    离开页面,然后回击:

    • 外页:0.4470929019483644
    • 内页:0.21300034290246206

    这表明内部页面正在被缓存,即使外部页面在URL中使用不同的GET参数调用它。出于某种原因,浏览器忽略了iframe请求新URL的事实;它只是加载旧的。

    Fiddler测试

    果然,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网址有任何想法?

14 个答案:

答案 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中的一个错误。

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

答案 4 :(得分:3)

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

在Javascript中,它可能看起来像:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + 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

都会导致同一页面。

您可以使用$_SERVER["QUERY_STRING"]

访问隐藏的网址参数

答案 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上,因此不太可能。