乐闻世界logo
搜索文章和话题

How to preventing iframe caching in browser

9 个月前提问
5 个月前修改
浏览次数279

6个答案

1
2
3
4
5
6

在浏览器中禁止 iframe 页面的缓存可以通过多种方法实现。这些方法通常需要在服务端设置 HTTP 头部或者在 iframe 标签的 URL 中添加额外的参数。以下是一些常见的方法:

1. 使用 HTTP 头部控制缓存

可以在服务器端设置一些 HTTP 头部信息以避免页面被缓存:

  • Cache-Control: no-store, no-cache, must-revalidate, max-age=0
  • Pragma: no-cache
  • Expires: 0

这些头部指令会告诉浏览器不要存储当前页面的任何副本,每次请求都需要向服务器重新获取。

例子:

如果你使用的是 Apache 服务器,可以在 .htaccess 文件中添加以下指令:

apache
<FilesMatch "\.html$"> Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0" Header set Pragma "no-cache" Header set Expires "0" </FilesMatch>

如果使用的是 PHP,可以在 PHP 脚本开头添加以下代码:

php
<?php header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); header("Pragma: no-cache"); header("Expires: 0"); ?>

2. 在 iframe URL 中添加时间戳

iframesrc 属性中添加一个唯一的查询字符串,如时间戳,也可以防止浏览器缓存页面。因为每次 URL 都是唯一的,浏览器会认为是新的资源,从而发送新的请求。

例子:

html
<iframe src="yourpage.html?nocache=123456789"></iframe>

其中 nocache=123456789 应该由服务器端生成的当前时间戳替换,以确保每次加载时 URL 都是唯一的。

使用 JavaScript 可以这样设置:

javascript
var iframe = document.getElementById('yourIframe'); iframe.src = 'yourpage.html?nocache=' + (new Date()).getTime();

3. 使用 meta 标签

虽然不是最可靠的方式,但您也可以在 iframe 页面的 <head> 部分使用 meta 标签来控制缓存行为。

例子:

html
<head> <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> </head>

总的来说,建议的最佳做法通常是在服务器端设置 HTTP 头部来控制缓存。这种方式是最可靠的,因为它不依赖于前端代码,而是直接由服务器告知浏览器如何处理缓存。

2024年6月29日 12:07 回复

这是 Firefox 中的一个错误:

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

尝试这个解决方法:

shell
<iframe src="webpage2.html?var=xxx" id="theframe"></iframe> <script> var _theframe = document.getElementById("theframe"); _theframe.contentWindow.location.href = _theframe.src; </script>
2024年6月29日 12:07 回复

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

在我的特定情况下,iframe 是通过 JS 构建的(但你可以通过 PHP、Ruby 等进行同样的操作),所以我只需使用Date.now()

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

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

2024年6月29日 12:07 回复

正如你所说,这里的问题不是iframe 内容缓存,而是iframe url 缓存

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

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

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

例如:

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

2- 迂回方式

服务器端,如此处所述,禁用为 iframe父页面提供的内容的内容缓存(两者都可以)。

使用额外的更改搜索参数从 javascript 设置 iframe url,如下所示:

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

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

2024年6月29日 12:07 回复

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

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

shell
frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
2024年6月29日 12:07 回复

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

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

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

我使用它的方式是 iframe 的 URL 最终看起来像这样: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"]

2024年6月29日 12:07 回复

你的答案