有没有一种方法可以让我把一些代码放在我的页面上,这样当有人访问一个网站时,它就会清空浏览器缓存,这样他们就可以查看更改了?
使用语言:ASP。净,VB。NET,当然还有HTML, CSS和jQuery。
有没有一种方法可以让我把一些代码放在我的页面上,这样当有人访问一个网站时,它就会清空浏览器缓存,这样他们就可以查看更改了?
使用语言:ASP。净,VB。NET,当然还有HTML, CSS和jQuery。
查看缓存控制和过期的META标签。
< meta http-equiv =" cache-control " content =" no-cache "> <META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 july 2002 11:12:01 GMT">
另一个常见的做法是在请求文件的末尾附加不断变化的字符串。例如:
<脚本类型=“文本/javascript”“src=”主。js?v = 12392823 " > < /脚本>
如果这是关于.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.
您可以检查这个链接,看看它是如何工作的。
并非如此。一种方法是在传递内容时发送适当的头文件,以迫使浏览器重新加载:
确保网页没有在所有浏览器上缓存。
如果你在SO上搜索“缓存头”或类似的东西,你会发现ASP。NET特定的示例。
另一种不太清晰但有时是唯一的方法,如果你不能控制服务器端的头,就是给被调用的资源添加一个随机的GET参数:
myimage.gif?random=1923849839
您是想清除缓存,还是只是确保当前(已更改的?)页面没有缓存?
如果是后者,那就应该如此简单
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
这里是在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
除了设置Cache-control: no-cache,如果你想每次刷新本地副本,你还应该将Expires头设置为-1(某些版本的IE似乎需要这样做)。
查看HTTP缓存-与服务器检查,始终发送If-Modified-Since
<meta http-equiv="pragma" content="no-cache" />
参见https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
不确定这是否真的对你有帮助,但这就是缓存在任何浏览器上的工作方式。当浏览器请求一个文件时,它应该总是向服务器发送请求,除非存在“脱机”模式。服务器将读取一些参数,如日期修改或标记。
服务器将为NOT MODIFIED返回一个304错误响应,浏览器将不得不使用它的缓存。如果标签在服务器端没有验证,或者修改的日期低于当前修改的日期,服务器应该返回带有新的修改日期或标签或两者的新内容。
如果没有缓存数据发送到浏览器,我猜行为是不确定的,浏览器可能会或可能不会缓存文件,不告诉他们是如何缓存的。如果您在响应中设置了缓存参数,它将正确缓存您的文件,然后服务器可能会选择返回一个304错误,或者返回新的内容。
这是应该做的。在url中使用随机参数或版本号更像一个黑客。
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。它将简单地使用缓存,直到达到过期日期或缓存被清除为止。
所以这是我的猜测,你有某种有效期,你应该使用最后修改标签或它们的混合,并确保没有过期日期。
如果人们倾向于频繁地刷新文件,而文件不会经常更改,那么设置一个大的过期日期可能是明智的。
我的2分钱!
对于静态资源,正确的缓存是使用带有每个部署或文件版本值的查询参数。这将在每次部署后清除缓存。
/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" />
不要忘记更新程序集版本。
更新2012
这是一个老问题,但我认为它需要一个更最新的答案,因为现在有一种方法可以更好地控制网站缓存。
在离线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开发者网络上使用应用程序缓存。
更新2016
网络上的事物变化很快。 这个问题是在2009年提出的,在2012年,我发布了一篇关于处理问题中描述的问题的新方法的更新。又过了4年,现在看来它已经被弃用了。感谢cgaldiolo在评论中指出这一点。
目前,截至2016年7月,HTML标准,第7.9节,脱机Web应用程序包括一个弃用警告:
这个特性正在从Web平台上移除。 (这是一个漫长的过程,需要很多年。)使用任何 此时非常不鼓励使用离线Web应用程序特性。 使用服务工作者代替。
在Mozilla开发者网络上使用应用程序缓存也是如此,我在2012年引用过:
已弃用该特性已从Web标准中移除。 虽然一些浏览器可能仍然支持它,但它仍在开发过程中 被删除。不要在旧的或新的项目中使用它。页面或Web应用程序 使用它可能会随时损坏。
请参见Bug 1204581 -如果启用service worker获取拦截,为AppCache添加弃用通知。
我有一个案例,我将在线拍摄客户端的照片,如果照片被更改,就需要更新div。浏览器仍然显示着旧照片。因此,我使用了调用随机GET变量的方法,该变量每次都是唯一的。这就是它,如果它能帮助到任何人的话
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
编辑 正如其他人指出的那样,下面是更有效的解决方案,因为它只会在图像被更改时重新加载图像,通过文件大小识别这种更改:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
我实现了这个简单的解决方案(还没有在生产环境中):
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的版本值是否低于当前版本,并执行a
location.reload(true);
...强制从服务器而不是缓存重新加载。
(显然,您可以使用cookie或其他持久客户端存储而不是localStorage)
我选择这个解决方案是因为它很简单,因为只维护一个“version .txt”文件就会强制重载整个站点。
queryString方法很难实现,而且也是缓存的(如果您从v1.1更改到以前的版本将从缓存加载,那么这意味着缓存不会刷新,将所有以前的版本保存在缓存中)。
我是一个小新手,我很感激你的专业检查和审查,以确保我的方法是一个很好的方法。
希望能有所帮助。
我也遇到过类似的问题,我是这样解决的:
In index.html file I've added manifest: <html manifest="cache.manifest"> In <head> section included script updating the cache: <script type="text/javascript" src="update_cache.js"></script> In <body> section I've inserted onload function: <body onload="checkForUpdate()"> In cache.manifest I've put all files I want to cache. It is important now that it works in my case (Apache) just by updating each time the "version" comment. It is also an option to name files with "?ver=001" or something at the end of name but it's not needed. Changing just # version 1.01 triggers cache update event. CACHE MANIFEST # version 1.01 style.css imgs/logo.png #all other files It's important to include 1., 2. and 3. points only in index.html. Otherwise GET http://foo.bar/resource.ext net::ERR_FAILED occurs because every "child" file tries to cache the page while the page is already cached. In update_cache.js file I've put this code: 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(); }
现在你只需更改文件,在manifest中你必须更新版本注释。现在访问index.html页面将更新缓存。
解决方案的部分不是我的,但我通过互联网找到了它们,并把它们放在一起,所以它是有效的。
很多答案都忽略了一点——大多数开发人员都很清楚关闭缓存是低效的。然而,在许多常见的情况下,效率并不重要,默认缓存行为被严重破坏。
这些包括嵌套的、迭代的脚本测试(大的一个!)和坏的第三方软件变通方法。这里给出的解决方案都不足以解决这种常见场景。大多数web浏览器都有过于激进的缓存,并且没有提供合理的方法来避免这些问题。
有一个小技巧可以使用。诀窍是在脚本标记中向文件名附加一个参数/字符串,并在文件更改时更改它。
<script src=“myfile.js?version=1.0.0”></script>
浏览器将整个字符串解释为文件路径,即使“?”后面的是参数。所以现在发生的是,下次当你更新你的文件时,只要改变你网站上script标签中的数字(示例<script src="myfile.js?version=1.0.1"></script>),每个用户的浏览器都会看到文件已经改变,并抓取一个新的副本。
更新URL为以下工作为我:
/ custom.js吗?id = 1
通过在?id=后添加一个唯一的数字,并随着新的变化而递增,用户不必按CTRL + F5来刷新缓存。或者,您可以在?id=后附加当前时间或Epoch的哈希或字符串版本
id=1520606295
强制浏览器清除缓存或重新加载正确的数据?我已经尝试了stackoverflow中描述的大多数解决方案,一些工作,但过了一会儿,它最终缓存并显示先前加载的脚本或文件。是否有另一种方法,将清除缓存(css, js等),并实际工作在所有浏览器?
I found so far that specific resources can be reloaded individually if you change the date and time on your files on the server. "Clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the server files cached will actually change the date and time of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
然后……剩下的程序…
It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping. By the way touch(); or alternatives work in many programming languages inclusive in javascript bash sh php and you can include or call them in html.
对于webpack用户:-
我在webpack配置中添加了chunkash。这解决了每次部署时缓存失效的问题。我们还需要注意index.html/ asset。清单不是缓存在你的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中更改System Verson并重命名文件夹并部署它。
我有同样的问题,我所做的就是改变文件名链接到我的index.html文件,然后进入index.html文件,更新他们的名字,不是最好的做法,但如果它工作。浏览器将它们视为新文件,因此它们会被重新下载到用户的设备上。
例子: 我想更新一个css文件,它的命名为styles.css,把它改成styles.css
进入index。html进行更新,并将其更改为
如果有兴趣,我已经找到了我的解决方案,让浏览器在。net MVC (.net fw 4.8)和使用包的情况下刷新.css和.js。 我想让浏览器仅在部署新程序集之后刷新缓存文件。
根据撒利亚多尼的回答,我的解决方案如下:
store your application base url in the web config app settings (the HttpContext is not yet available at runtime during the RegisterBundle...), then make this parameter changing according to the configuration (debug, staging, release...) by the xml transform In BundleConfig RegisterBundles get the assembly version by the means of reflection, and... ...change the default tag format of both styles and scripts so that the bundling system generates link and script tags appending a query string parameter on them.
下面是代码
public static void RegisterBundles(BundleCollection bundles)
{
string baseUrl = system.Configuration.ConfigurationManager.AppSettings["by.app.base.url"].ToString();
string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Styles.DefaultTagFormat = $"<link href='{baseUrl}{{0}}?v={assemblyVersion}' rel='stylesheet'/>";
Scripts.DefaultTagFormat = $"<script src='{baseUrl}{{0}}?v={assemblyVersion}'></script>";
}
你会得到这样的标签
<script src="https://example.org/myscriptfilepath/script.js?v={myassemblyversion}"></script>
您只需要记住在部署之前构建一个新版本。
Ciao