强制浏览器清除缓存

时间:2009-12-17 16:23:37

标签: html caching browser meta-tags

有没有办法可以在我的网页上放置一些代码,以便当有人访问某个网站时,它会清除浏览器缓存,以便他们查看更改?

使用的语言:ASP.NET,VB.NET,当然还有HTML,CSS和jQuery。

19 个答案:

答案 0 :(得分:304)

如果这是.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.

您可以查看此link,看看它是如何运作的。

答案 1 :(得分:93)

查看cache-controlexpires META标记。<​​/ p>

<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>

答案 2 :(得分:72)

2012年更新

这是一个老问题,但我认为它需要更新的答案,因为现在有一种方法可以更好地控制网站缓存。

Offline Web Applications(实际上是任何HTML5网站)applicationCache.swapCache()可用于更新网站的缓存版本,而无需手动重新加载页面。

这是来自HTML5 Rocks上Beginner's Guide to Using the Application Cache的代码示例,说明如何将用户更新到您网站的最新版本:

// 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开发人员网络上的Using the application cache

2016年更新

网上的事情变化很快。 这个问题在2009年被问到,2012年我发布了一个关于处理问题中描述的问题的新方法的更新。又过了4年,现在似乎已经被弃用了。感谢 cgaldiolo 在评论中指出它。

目前,截至2016年7月,HTML Standard, Section 7.9, Offline Web applications包含弃用警告:

  

此功能正在从Web平台中删除。   (这是一个需要很多年的漫长过程。)使用任何一个   目前,离线Web应用程序功能非常不受欢迎。   改为使用服务工作者。

我在2012年引用的Mozilla开发者网络上的Using the application cache也是如此:

  

已弃用
此功能已从Web标准中删除。   虽然有些浏览器可能仍然支持它,但它正在进行中   被丢弃。不要在旧项目或新项目中使用它。页面或Web应用程序   使用它可能会随时中断。

另见Bug 1204581 - Add a deprecation notice for AppCache if service worker fetch interception is enabled

答案 3 :(得分:26)

不是这样的。一种方法是在传递内容时发送适当的标头以强制浏览器重新加载:

Making sure a web page is not cached, across all browsers.

如果你在SO上搜索"cache header"或类似内容,你会发现ASP.NET特定的例子。

另一个不太干净但有时只有在服务器端无法控制标头的方法时,才会向正在调用的资源添加一个随机GET参数:

myimage.gif?random=1923849839

答案 4 :(得分:14)

对于静态资源,正确的缓存是使用查询参数以及每个部署或文件版本的值。这将在每次部署后清除缓存。

/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" />

不要忘记更新程序集版本。

答案 5 :(得分:7)

我有一个案例,我会在网上拍摄客户的照片,如果照片被更改,则需要更新div。浏览器仍然显示旧照片。所以我使用了调用随机GET变量的hack,每次都是唯一的。这是它可以帮助任何人

<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...

EDIT 正如其他人所指出的,以下是更有效的解决方案,因为它只会在更改时重新加载图像,并通过文件大小识别此更改:

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"

答案 6 :(得分:6)

我有类似的问题,这就是我解决它的方法:

  1. index.html文件中,我添加了清单:

    <html manifest="cache.manifest">
    
  2. <head>部分包含更新缓存的脚本:

    <script type="text/javascript" src="update_cache.js"></script>
    
  3. <body>部分我已插入onload函数:

    <body onload="checkForUpdate()">
    
  4. cache.manifest我已经放置了我要缓存的所有文件。现在重要的是,它只适用于我的情况(Apache),每次更新&#34;版本&#34;评论。使用&#34;?ver = 001&#34;命名文件也是一个选项。或名称末尾的某些内容,但不需要。仅更改# 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
    

    发生的原因是每个孩子&#34;文件尝试在页面已缓存时缓存页面。

  5. 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();
    }
    
  6. 现在您只需更改文件,在清单中您必须更新版本注释。现在访问index.html页面将更新缓存。

    解决方案的各个部分都不是我的,但我已经通过互联网找到它们并将它们放在一起以便它可以工作。

答案 7 :(得分:4)

很多答案都没有提到 - 大多数开发人员都清楚地知道关闭缓存是效率低下的。但是,在许多常见情况下,效率并不重要,并且默认缓存行为严重受损。

这些包括嵌套的迭代脚本测试(最重要的一个!)和破坏的第三方软件解决方法。这里给出的解决方案都不足以解决这些常见情况。大多数Web浏览器都是过于激进的缓存,并没有提供任何明智的方法来避免这些问题。

答案 8 :(得分:2)

答案 9 :(得分:2)

不确定这是否真的对您有所帮助,但这就是缓存应该如何在任何浏览器上运行。当浏览器请求文件时,它应始终向服务器发送请求,除非存在“离线”模式。服务器将读取一些参数,如date modified或etags。

服务器将为NOT MODIFIED返回304错误响应,浏览器必须使用其缓存。如果etag未在服务器端验证或修改日期低于当前修改日期,则服务器应返回具有新修改日期或etags或两者的新内容。

如果没有缓存数据发送到浏览器,我猜这个行为是不确定的,浏览器可能会也可能不会缓存不告诉它们如何被缓存的文件。如果在响应中设置缓存参数,它将正确缓存文件,然后服务器可能会选择返回304错误或新内容。

这是应该怎么做的。在网址中使用随机参数或版本号更像是黑客而不是任何东西。

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美分!

答案 10 :(得分:2)

将URL更新为以下内容适用于我:

/custom.js?id=1

通过在?id=之后添加唯一编号并将其递增以进行新更改,用户无需按CTRL + F5即可刷新缓存。或者,您可以在?id=

之后附加当前时间或Epoch的哈​​希或字符串版本

?id=1520606295

这样的东西

答案 11 :(得分:1)

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

答案 12 :(得分: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所在位置的小文件:

&#34; versio.txt&#34;:

v00.5.0014

在我的所有页面中调用此函数,因此在加载时检查localStorage的版本值是否低于当前版本并执行

location.reload(true);

...强制从服务器重新加载而不是从缓存中重新加载。

(显然,您可以使用Cookie或其他持久客户端存储来代替localStorage)

我选择这个解决方案的原因很简单,因为它只保留一个文件&#34; versio.txt&#34;将迫使整个网站重新加载。

queryString方法很难实现并且也被缓存(如果从v1.1更改为先前版本将从缓存加载,则表示缓存未刷新,将所有先前版本保留在缓存中)。 / p>

我是一个小新手,我提供了专业检查和帮助。审查以确保我的方法是一个好方法。

希望它有所帮助。

答案 13 :(得分:0)

除了设置Cache-control:no-cache之外,如果您希望每次刷新本地副本(某些版本的IE似乎需要这样),您还应该将Expires标头设置为-1。

请参阅HTTP Cache - check with the server, always sending If-Modified-Since

答案 14 :(得分:0)

可以使用一个技巧。技巧是将参数/字符串附加到脚本标记中的文件名,并在提交更改时进行更改。

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

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

答案 15 :(得分:0)

强制浏览器清除缓存或重新加载正确的数据?我已经尝试过stackoverflow中描述的大多数解决方案,有些工作,但过了一会儿,它最终会缓存并显示以前加载的脚本或文件。还有另一种方法可以清除缓存(css,js等),并且实际上可以在所有浏览器上运行吗?

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

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

然后......你的其他程序......

我花了一些时间来解决这个问题(因为许多浏览器对不同的命令采取不同的行动,但他们都检查文件的时间并与浏览器中下载的副本进行比较,如果不同的日期和时间,将进行刷新) ,如果你不能按照假设的正确方式,总会有另一个可用的更好的解决方案。最好的问候和快乐的露营。顺便说一下touch();或者替代品在许多编程语言中工作,包括在javascript bash sh php中,你可以在html中包含或调用它们。

答案 16 :(得分:0)

如果您是 Wordpress 开发人员,我有一些好消息要告诉您。

只需搜索、安装并激活名为:reBusted 的 Wordpress 插件即可。

无需配置。

如果内容已更新,它将自动强制刷新缓存,并完全可靠地解决了此问题。已在数百个客户 Wordpress 网站上进行测试和使用 - 在任何地方都能完美运行。

不能推荐它。

如果您使用 Wordpress,这是迄今为止解决此问题的最佳选择和最优雅的解决方案。

享受吧!

答案 17 :(得分:0)

对于 webpack 用户:-

我在 webpack 配置中使用 chunkhash 添加了时间。这解决了我在每次部署时使缓存无效的问题。此外,我们需要注意 index.html/asset.manifest 不会缓存在您的 CDN 或浏览器中。 webpack 配置中块名称的配置将如下所示:-

文件名:[chunkhash]-${Date.now()}.js

或者如果您使用的是 contenthash 则

文件名:[contenthash]-${Date.now()}.js

答案 18 :(得分:-1)

是否要清除缓存,或者只是确保当前(已更改的?)页面未缓存?

如果是后者,它应该像

一样简单
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">