部署后强制刷新缓存

22

如果您无法更改引用文件的URI(例如,无法添加时间戳参数),是否有一种方法来强制客户端缓存重新加载HTML文件?

以下是我的情况:

  • 插件部署到1000个用户
  • 该插件加载example.com/page.html,该页面调用script.js
  • 资源URIexample.com/page.html不能更改(需要更新插件)
  • page.html已更改。我需要清除用户缓存中的旧page.html,以便新的page.html可以加载。

有什么想法吗? Htaccess?旧和新的page.html调用的PHP API?

谢谢!

4个回答

35
如果页面已经被浏览器缓存,很难告诉它不要使用缓存版本,因为在确定缓存版本过期之前,它可能不会再次检查。你只能给所有用户发送一封邮件,告诉他们按ctrl+f5键:)
但是,浏览器可能会尝试使用HEAD请求来检查修改时间戳,然后提供其缓存版本。在这种情况下,以下方法将对您有所帮助。
浏览器使用HTTP标准头从您的Web服务器协商其内容。如果您想要告诉浏览器不要缓存文件,则必须发送适当的HTTP标头。如果您想在PHP中执行此操作,则可以使用header函数向浏览器发送适当的HTTP标头:
header('Cache-Control: no-cache');
header('Pragma: no-cache');

如果必须通过HTML完成,您可以在页面头部执行以下操作:
<meta http-equiv="Expires" content="Tue, 01 Jan 1995 12:12:12 GMT">
<meta http-equiv="Pragma" content="no-cache">

您无法确定浏览器是否会遵守您的请求不缓存页面。还有一些其他的东西,比如ETag等等,但坦率地说,如果页面已经被缓存,我认为这些方法并不能帮助您。


更新

从HTTP/1.1规范中响应可缓存性得知:

如果响应中既没有缓存验证器,也没有显式的过期时间,我们不希望它被缓存,但是某些缓存可能会违反这个期望(例如,在几乎没有网络连接时)。


不确定这是否能实现我的目标。我可以控制的 PHP 文件是一个 API,由 example.html 中的 js 文件调用。您提供的 header 解决方案似乎只适用于 PHP 文件本身?还是它适用于同一域上的所有资源?至于 HTML 解决方案,如果旧的 example.html 文件已经包含了那些标签,那么它就可以工作,但正如上面所述,对于我的情况并非如此。 - Kyle Cureau
换句话说,我正在尝试在已经缓存的旧example.html上加载新的example.html - Kyle Cureau
遗憾的是,一旦浏览器缓存了某些内容,你就无法对其进行太多操作。好消息是,大多数浏览器不会长时间缓存这些内容。这只是生活的事实,我很抱歉。 - user895378
PHP API可能只是一厢情愿的想法,但你应该可以在Apache层面上强制刷新。无论如何,幸好HTML不会被长时间缓存。如果没有什么奇迹般的解决方案,我就放弃了并接受你的答案。 - Kyle Cureau
是的,我无法想象浏览器会缓存超过一天(最多)的任何内容,而不至少检查服务器以查看文件是否已被修改。我认为通常情况下是一两个小时左右,除非您的服务器明确告知它们将其缓存更长时间。 - user895378

4
也许可以使用PHP在JavaScript调用中添加时间戳。然后你可以在整个过程中运行此代码......例如:

check_if_cache_should_be_disabled.php

<?php
$deployment_flag = true; // Uncomment this if you want to disable normal cache.
//$deployment_flag = false // Uncomment this if you want to enable normal cache.
?>

page.php

<script src="/js/script.js<?php 
require('check_if_cache_should_be_disabled.php');
//  File Get Contents can be used for a remote server
//file_get_contents('http://yourserver.com/check_if_cache_should_be_disabled.php');
if ($deployment_flag == true) {
print ( '?ts='.date() );
}
?>"></script>

0

您可以更改文件名,例如page_v2.html,这将使浏览器将该页面作为新页面加载。


我发现即使这样做对Chrome也没有帮助。它仍然会愉快地继续加载甚至不存在的文件。 - nuander
@nuander 的确如此。Firefox 有时甚至对使用 ?<timestamp> 的 css 和 js 资源也很顽固,但 Chrome 似乎更糟糕。有时行为看起来不一致,这可能会让人抓狂。 - KevinHJ
我见过一些网页使用 .php 文件来提供 css 和 js 资源。我猜这是为了发送头文件以强制重新加载,例如 Cache-Control: no-store, max-age=0。 - KevinHJ

0
这个答案可能过于简单,但你可以在文件末尾附加一个GET值,其中包含文件版本。现代浏览器通常将其视为新版本,并忽略以前的缓存并获取最新版本。因此,当您希望缓存最新代码时,只需更新版本即可。
例如:
<script type="javascript" src="example.js?version=2.0.8"></script>

你甚至可以编写一个PHP脚本,当文件根据某些特定参数(如“最后更新”)发生更改时,自动为您执行此操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接