有没有办法可以在我的页面上放置一些代码,这样当有人访问一个站点时,它会清除浏览器缓存,以便他们可以查看更改?
使用的语言:ASP.NET、VB.NET,当然还有 HTML、CSS 和 jQuery。
如果这即将发生.css
并.js
发生变化,一种方法是“缓存破坏”是通过_versionNo
在每个版本的文件名中附加“”之类的内容。例如:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
或者在文件名之后执行:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
您可以查看此链接以了解它是如何工作的。
这是一个老问题,但我认为它需要一个更新的答案,因为现在有一种方法可以更好地控制网站缓存。
在离线 Web 应用程序(实际上是任何 HTML5 网站)applicationCache.swapCache()
中,可用于更新网站的缓存版本,而无需手动重新加载页面。
这是在 HTML5 Rocks 上使用应用程序缓存的初学者指南中的一个代码示例,解释了如何将用户更新到您网站的最新版本:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
另请参阅使用Mozilla 开发人员网络上的应用程序缓存以获取更多信息。
网络上的事情变化很快。这个问题是在 2009 年提出的,在 2012 年我发布了一个关于处理问题中描述的问题的新方法的更新。又过了 4 年,现在看来它已经被弃用了。感谢cgaldiolo在评论中指出这一点。
目前,截至 2016 年 7 月,HTML 标准第 7.9 节,离线 Web 应用程序包含一个弃用警告:
此功能正在从 Web 平台中删除。(这是一个需要很多年的漫长过程。)此时强烈建议不要使用任何离线 Web 应用程序功能。改为使用服务人员。
我在 2012 年提到的在 Mozilla 开发者网络上使用应用程序缓存也是如此:
已弃用
此功能已从 Web 标准中删除。尽管某些浏览器可能仍然支持它,但它正在被删除。不要在旧项目或新项目中使用它。使用它的页面或 Web 应用程序可能随时中断。
不是这样的。一种方法是在交付内容时发送适当的标头以强制浏览器重新加载:
如果您在 SO 上搜索"cache header"
或类似的内容,您将找到 ASP.NET 特定示例。
如果您无法控制服务器端的标头,另一种不太干净但有时唯一的方法是向正在调用的资源添加随机 GET 参数:
myimage.gif?random=1923849839
对于静态资源,正确的缓存将是使用带有每个部署或文件版本值的查询参数。这将在每次部署后清除缓存。
/Content/css/Site.css?version={FileVersionNumber}
这是 ASP.NET MVC 示例。
<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
不要忘记更新程序集版本。
我有类似的问题,这就是我解决它的方法:
在index.html
文件中我添加了清单:
<html manifest="cache.manifest">
在<head>
部分包含更新缓存的脚本:
<script type="text/javascript" src="update_cache.js"></script>
在<body>
我插入 onload 函数的部分中:
<body onload="checkForUpdate()">
在cache.manifest
我已经放置了所有我想要缓存的文件。现在很重要的是,它在我的案例(Apache)中只需每次更新“版本”注释即可。使用“?ver=001”或名称末尾的其他名称命名文件也是一个选项,但它不是必需的。更改只会# version 1.01
触发缓存更新事件。
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
仅在 index.html中包含 1.、2. 和 3. 点很重要。除此以外
GET http://foo.bar/resource.ext net::ERR_FAILED
发生是因为每个“子”文件都试图在页面已经缓存时缓存页面。
在update_cache.js
文件中,我放了以下代码:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
现在您只需更改文件,并且在清单中您必须更新版本注释。现在访问 index.html 页面将更新缓存。
解决方案的部分不是我的,但我通过互联网找到了它们并将它们放在一起以便它工作。
我有一个案例,我会在网上为客户拍照,如果照片发生变化,我需要更新 div。浏览器仍在显示旧照片。所以我使用了调用随机 GET 变量的技巧,每次都是唯一的。如果它可以帮助任何人
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
编辑正如其他人所指出的,以下是更有效的解决方案,因为它只会在图像发生更改时重新加载图像,并通过文件大小识别此更改:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
很多答案都没有抓住重点——大多数开发人员都清楚关闭缓存是低效的。但是,在许多常见情况下,效率并不重要,默认缓存行为被严重破坏。
其中包括嵌套的、迭代的脚本测试(最重要的!)和损坏的第三方软件变通办法。此处给出的解决方案都不足以解决此类常见情况。大多数 Web 浏览器的缓存过于激进,并且没有提供任何明智的方法来避免这些问题。
将 URL 更新为以下内容对我有用:
/custom.js?id=1
通过在后面添加一个唯一的数字?id=
并为新的更改增加它,用户不必按下来CTRL + F5
刷新缓存。或者,您可以在之后附加当前时间或 Epoch 的哈希或字符串版本?id=
就像是?id=1520606295
<meta http-equiv="pragma" content="no-cache" />
另请参阅https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
这是关于在 ASP.NET 中设置缓存的 MDSN 页面。
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
不确定这是否真的可以帮助您,但这就是缓存在任何浏览器上的工作方式。当浏览器请求一个文件时,它应该总是向服务器发送一个请求,除非有“离线”模式。服务器将读取一些参数,如修改日期或 etags。
服务器将返回未修改的 304 错误响应,并且浏览器将不得不使用其缓存。如果 etag 在服务器端无效或修改日期低于当前修改日期,则服务器应返回带有新修改日期或 etag 或两者的新内容。
如果没有缓存数据发送到浏览器,我猜行为是不确定的,浏览器可能缓存也可能不缓存不告诉它们如何缓存的文件。如果您在响应中设置缓存参数,它将正确缓存您的文件,然后服务器可能会选择返回 304 错误或新内容。
这就是应该这样做的方式。在 url 中使用随机参数或版本号更像是一种 hack。
http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs-过期标头vs-etag/
看完后,我看到还有一个过期日期。如果您有问题,可能是您设置了过期日期。换句话说,当浏览器缓存您的文件时,由于它有一个到期日期,它不应该在该日期之前再次请求它。换句话说,它永远不会向服务器询问文件,也永远不会收到未修改的 304。它只会使用缓存,直到到期日期或缓存被清除。
所以这是我的猜测,你有某种到期日期,你应该使用最后修改的 etag 或它们的混合,并确保没有到期日期。
如果人们倾向于刷新很多并且文件没有得到很多更改,那么设置一个大的到期日期可能是明智的。
我的2美分!
我实现了这个适用于我的简单解决方案(尚未在生产环境中使用):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
我有一个小文件位于 html 所在的位置:
“版本.txt”:
v00.5.0014
这个函数在我的所有页面中都被调用,所以在加载它时会检查 localStorage 的版本值是否低于当前版本并执行
location.reload(true);
...强制从服务器而不是从缓存重新加载。
(显然,您可以使用 cookie 或其他持久客户端存储来代替 localStorage)
我选择了这种简单的解决方案,因为只维护一个文件“versio.txt”将强制重新加载整个站点。
queryString 方法很难实现并且也是缓存的(如果你从 v1.1 更改到以前的版本将从缓存中加载,那么这意味着缓存没有被刷新,所有以前的版本都在缓存中)。
我是一个小新手,我会感谢您的专业检查和审查,以确保我的方法是一个好方法。
希望能帮助到你。
除了设置 Cache-control: no-cache 之外,如果您希望每次都刷新本地副本,还应该将 Expires 标头设置为 -1(某些版本的 IE 似乎需要这样做)。
可以使用一个技巧。技巧是将参数/字符串附加到脚本标记中的文件名,并在文件更改时更改它。
<script src="myfile.js?version=1.0.0"></script>
浏览器将整个字符串解释为文件路径,即使“?”后面是什么。是参数。所以现在发生的事情是,下次更新文件时,只需更改网站上脚本标记中的数字(示例<script src="myfile.js?version=1.0.1"></script>
),每个用户浏览器都会看到文件已更改并获取新副本。
强制浏览器清除缓存或重新加载正确的数据?我已经尝试了stackoverflow中描述的大多数解决方案,有些工作,但过了一会儿,它最终会缓存并显示以前加载的脚本或文件。是否有另一种方法可以清除缓存(css、js 等)并在所有浏览器上实际工作?
到目前为止,我发现如果您更改服务器上文件的日期和时间,可以单独重新加载特定资源。“清除缓存”并不像应有的那么容易。我没有清除浏览器上的缓存,而是意识到“触摸”缓存的服务器文件实际上会更改缓存在服务器上的源文件的日期和时间(在 Edge、Chrome 和 Firefox 上测试),并且大多数浏览器会自动下载最您服务器上最新内容的最新副本(代码、图形以及任何多媒体)。我建议您在程序运行之前复制服务器上最新的脚本和“做触摸的事情”解决方案,这样它会将所有问题文件的日期更改为最新的日期和时间,然后下载一个新的副本到您的浏览器:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
然后......你的程序的其余部分......
我花了一些时间来解决这个问题(因为许多浏览器对不同命令的行为不同,但它们都会检查文件的时间并与您在浏览器中下载的副本进行比较,如果日期和时间不同,则会进行刷新),如果您不能走所谓的正确方式,总有另一种可用且更好的解决方案。最好的问候和快乐的露营。顺便说一下 touch(); 或替代方案适用于许多编程语言,包括 javascript bash sh php,您可以在 html 中包含或调用它们。
对于 webpack 用户:-
我在我的 webpack 配置中添加了 chunkhash 的时间。这解决了我在每次部署时使缓存失效的问题。我们还需要注意 index.html/asset.manifest 没有缓存在您的 CDN 或浏览器中。webpack 配置中的块名称配置如下所示:-
文件名:[chunkhash]-${Date.now()}.js
或者如果您使用的是 contenthash,那么
文件名:[contenthash]-${Date.now()}.js
这是我在我的一个应用程序中使用 PHP 解决的简单解决方案。
所有 JS 和 CSS 文件都放在一个带有版本名称的文件夹中。示例:“1.0.01”
root\1.0.01\JS
root\1.0.01\CSS
创建了一个 Helper 并在那里定义了版本号
<?php
function system_version()
{
return '1.0.07';
}
并链接 JS 和 SCC 文件,如下所示
<script src="<?= base_url(); ?>/<?= system_version();?>/js/generators.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?= base_url(); ?>/<?= system_version(); ?>/css/view-checklist.css" />
每当我对任何 JS 或 CSS 文件进行更改时,我都会更改 Helper 中的系统版本并重命名文件夹并部署它。
你想清除缓存,还是只是确保你当前的(更改的?)页面没有被缓存?
如果是后者,它应该很简单
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
如果您是 Wordpress 开发人员,我有一些好消息要告诉您。
只需搜索、安装并激活名为:reBusted 的 Wordpress 插件。
无需配置。
如果内容已更新,它将自动强制刷新缓存,并且完全可靠地解决了此问题。在数百个客户端 Wordpress 网站上测试和使用——在任何地方都能完美运行。
不能推荐它。
如果您使用 Wordpress,这是迄今为止您最好的选择和最优雅的解决方案。
享受!