Answers:
如果这是关于.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.
您可以查看此链接以查看其工作方式。
script.js?v=1.2
。(或者,如果您不跟踪版本,只需使用文件上次修改的时间即可,这更容易实现)。不知道那是以前的评论者的意思!
<link />
动态呈现标签,并将应用程序的版本作为查询字符串参数注入。或者,某些CMS将附加“客户端资源版本”作为CMS范围的附加设置-网站的管理员可以手动增加该版本nr,并且CMS的更新还可以自动更新它。底线:您需要动态呈现文件URL。
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
另一种常见的做法是将不断变化的字符串附加到请求文件的末尾。例如:
<script type="text/javascript" src="main.js?v=12392823"></script>
这是一个古老的问题,但是我认为它需要更新的答案,因为现在有一种方法可以更好地控制网站缓存。
在“ 脱机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年,我发布了有关处理问题中所述问题的新方法的更新。又过了四年,现在看来它已经过时了。感谢cgaldiolo在评论中指出。
当前,从2016年7月开始,HTML标准的第7.9节“脱机Web应用程序”包含弃用警告:
该功能正在从Web平台中删除。(这是一个耗时多年的漫长过程。)强烈建议您此时不使用任何脱机Web应用程序功能。请改用服务人员。
在2012年引用的Mozilla开发人员网络上使用应用程序缓存也是如此:
不推荐使用
此功能已从Web标准中删除。尽管某些浏览器可能仍支持它,但是它正在被删除。不要在新旧项目中使用它。使用它的页面或Web应用程序可能随时中断。
另请参见Bug 1204581-如果启用了Service Worker Fetch拦截,则为AppCache添加弃用通知。
并非如此。一种方法是在传递内容时发送适当的标头,以强制浏览器重新加载:
如果"cache header"
在SO上进行搜索或类似的搜索,您将找到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" />
不要忘记更新程序集版本。
?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
我有类似的问题,这就是我解决的方法:
在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")?>"
<meta http-equiv="pragma" content="no-cache" />
另请参阅/programming/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错误或新内容。
这是应该做的。在网址中使用随机参数或版本号更像是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- expire-header-vs-etag /
阅读后,我看到还有一个过期日期。如果有问题,则可能是您设置了到期日期。换句话说,当浏览器缓存文件时,由于它具有到期日期,因此不必在该日期之前再次请求它。换句话说,它将永远不会向服务器请求文件,也永远不会收到未修改的304。它将仅使用缓存,直到达到到期日期或清除缓存为止。
所以这就是我的猜测,您有某种到期日期,应该使用上次修改的etags或所有这些的混合使用,并确保没有到期日期。
如果人们倾向于刷新很多并且文件没有做太多更改,那么设置一个较大的到期日期可能是明智的。
我的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所在的位置有一个小文件:
“ versio.txt”:
v00.5.0014
我的所有页面都调用了此函数,因此在加载时会检查localStorage的版本值是否低于当前版本,并执行
location.reload(true);
...强制从服务器而不是从缓存重新加载。
(显然,可以使用cookie或其他持久客户端存储来代替localStorage)
我之所以选择此解决方案是因为其简单性,因为仅维护单个文件“ versio.txt”将强制重新加载整个网站。
queryString方法难以实现,而且也会被缓存(如果从v1.1更改为以前的版本,则会从缓存中加载,这意味着不会刷新缓存,将所有以前的版本保留在缓存中)。
我是个新手,因此希望您能通过专业的检查和审查,以确保我的方法是一种很好的方法。
希望能帮助到你。
除了设置Cache-control:no-cache外,如果您希望每次都刷新本地副本(某些版本的IE似乎需要这样做),还应该将Expires标头设置为-1。
强制浏览器清除缓存或重新加载正确的数据?我已经尝试了stackoverflow中描述的大多数解决方案,并且做了一些工作,但是过了一会儿,它最终还是缓存并显示了先前加载的脚本或文件。还有另一种方法可以清除缓存(css,js等)并在所有浏览器上正常工作吗?
到目前为止,我发现如果您更改服务器上文件的日期和时间,则可以分别重新加载特定的资源。“清除缓存”并不是那么容易。我没有清除浏览器上的缓存,而是意识到“触摸”缓存的服务器文件实际上会更改缓存在服务器上的源文件的日期和时间(在Edge,Chrome和Firefox上测试),并且大多数浏览器会自动下载最多服务器上内容的最新副本(代码,图形以及任何多媒体)。我建议您只复制服务器上最新的脚本,然后在程序运行之前“执行触摸操作”解决方案,这样它将把所有问题文件的日期更改为最新的日期和时间,然后下载新的副本。到您的浏览器:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
然后...程序的其余部分...
我花了一些时间解决此问题(因为许多浏览器对不同命令的操作不同,但是它们都检查文件的时间并与浏览器中下载的副本进行比较,如果日期和时间不同,则会进行刷新),如果不能以正确的方式前进,总是有另一个可用且更好的解决方案。最好的问候和快乐的露营。顺便说一下touch(); 或替代方法可以在javascript bash sh php等许多编程语言中工作,您可以在html中包含或调用它们。
您要清除缓存,还是只是确保当前(已更改?)页面未缓存?
如果是后者,则应尽可能简单
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">