强制浏览器清除缓存

361

有没有一种方法可以在我的网页上放置一些代码,以便当有人访问该网站时,清除浏览器缓存,这样他们就可以查看更改内容了?

使用的语言:ASP.NET,VB.NET以及HTML,CSS和jQuery。


一个不错的“清除缓存”的解决方案或变通方法可以在这里找到:https://dev59.com/nWsz5IYBdhLWcg3wBzfi#43676353 - caramba
2023年,您可以使用Clear-Site-Data HTTP头部;有关详细信息,请参阅此答案 - undefined
23个回答

2

1
我实现了这个对我有效的简单解决方案(尚未在生产环境中使用):
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更改到较早版本,则会从缓存中加载,这意味着缓存未被清除,保留了所有先前的版本)。

我有点新手,希望您能进行专业的检查和审查,以确保我的方法是一个好方法。

希望对您有所帮助。


1

这里是关于在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

1

有一个技巧可以使用。这个技巧是在脚本标签的文件名后附加一个参数/字符串,并在文件更改时更改它。

<script src="myfile.js?version=1.0.0"></script>

浏览器将整个字符串解释为文件路径,即使“?”后面的内容是参数。所以现在发生的情况是,下次更新文件时,只需更改网站上脚本标记中的数字(例如<script src="myfile.js?version=1.0.1"></script>),每个用户的浏览器都会看到文件已更改并获取新副本。


1

不确定这是否真的能帮到你,但这就是缓存在任何浏览器上应该如何工作。当浏览器请求文件时,除非有“离线”模式,它应该始终向服务器发送请求。服务器将读取一些参数,例如修改日期或ETags。

服务器将返回一个304错误响应以表示未修改,浏览器必须使用其缓存。如果ETag在服务器端无法验证或修改日期低于当前修改日期,则服务器应返回具有新修改日期或ETags或两者的新内容。

如果没有缓存数据发送到浏览器,我想行为是不确定的,浏览器可能会或可能不会缓存不告诉它们如何缓存的文件。如果您在响应中设置缓存参数,它将正确地缓存您的文件,然后服务器可以选择返回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未修改的响应。它将简单地使用缓存。

所以这就是我的猜测,您有某种过期日期,应该使用最后修改的ETag或混合使用,并确保没有过期日期。

如果人们经常刷新而文件并没有经常更改,那么设置一个大的过期日期可能是明智的选择。

以上仅供参考!


0

如何强制浏览器清除缓存或重新加载正确的数据?我尝试了stackoverflow中描述的大多数解决方案,有些可以工作,但过一会儿后,它最终仍然会缓存并显示先前加载的脚本或文件。是否有另一种方法可以清除所有浏览器的缓存(css、js等)并实际上起作用?

到目前为止,我发现特定资源可以单独重新加载,如果您更改服务器上文件的日期和时间。 "清除缓存"并不像应该那么容易。我意识到,与其在我的浏览器上清除缓存,不如“触摸”服务器文件缓存,实际上会更改服务器上缓存的源文件的日期和时间(在Edge、Chrome和Firefox上测试),大多数浏览器将自动下载服务器上最新的内容(代码、图形和任何多媒体)。我建议您在程序运行之前只需复制服务器上最新的脚本并使用“触摸”解决方案,这样它就会将所有问题文件的日期更改为最新日期和时间,然后将一个新的副本下载到您的浏览器:

<?php
   touch('/www/sample/file1.css');
   touch('/www/sample/file2.js');
?>

然后...你程序的其余部分...

我花了一些时间解决这个问题(因为许多浏览器对不同的命令有不同的反应,但它们都会检查文件的时间并将其与您在浏览器中下载的副本进行比较。如果日期和时间不同,则会刷新),如果您不能按照所谓的正确方式操作,总会有另一个可用且更好的解决方案。最好的问候和愉快的露营。顺便说一下,touch(); 或类似的东西可以在许多编程语言中使用,包括JavaScript、Bash、sh和PHP,并且您可以在HTML中包含或调用它们。


1
如果文件已经被修改,那么时间戳已经改变了,所以强制再次修改没有任何好处。 - Fusca Software
touch命令不会改变文件本身,它只是修改了文件的日期和时间属性,使得浏览器误认为该文件是新版本并重新下载。 - Luis H Cabrejo

0

如果您感兴趣,我已经找到了解决方案,可以在.NET MVC (.net fw 4.8)和使用bundles的上下文中获取浏览器刷新.css和.js文件的方法。我想让浏览器仅在部署新程序集后刷新缓存文件。

在Paulius Zaliaduonis的回复基础上,我的解决方案如下:

  1. 将应用程序基本URL存储在Web配置应用程序设置中(在RegisterBundle...期间HttpContext尚不可用),然后通过xml转换使此参数根据配置(调试、暂存、发布等)进行更改
  2. 在BundleConfig RegisterBundles中通过反射获取程序集版本,然后...
  3. ...更改样式和脚本的默认标记格式,以便捆绑系统在它们上面生成链接和脚本标记并附加查询字符串参数。

以下是代码:

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>

在部署之前,您只需要记得构建一个新版本即可。

再见


0

这是我在使用PHP解决一个应用程序中的简单解决方案。

所有JS和CSS文件都放置在一个带有版本名称的文件夹中。例如:"1.0.01"

root\1.0.01\JS
root\1.0.01\CSS

创建了一个帮助类,并在那里定义了版本号。
<?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中更改系统版本并重命名文件夹,然后部署它。

0

0

对于webpack用户:

我在我的webpack配置中添加了带有chunkhash的时间。这解决了每次部署都需要使缓存失效的问题。同时,我们需要注意确保index.html/asset.manifest不会被CDN或浏览器缓存。在webpack配置中,块名称的配置如下:

fileName: [chunkhash]-${Date.now()}.js

或者如果您使用contenthash,则为

fileName: [contenthash]-${Date.now()}.js


请格式化您的答案,以获得更好的可视化效果。我们使用Markdown。您可以编辑您的答案。 - Danizavtz

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