强制浏览器清除缓存

Ada*_*dam 268 html browser caching meta-tags

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

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

Fer*_*min 325

如果这是关于.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.
Run Code Online (Sandbox Code Playgroud)

或者在文件名后执行:

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.
Run Code Online (Sandbox Code Playgroud)

您可以查看此链接,了解它是如何工作的.

  • 更好的是保持文件名不变,但将版本号附加为查询字符串参数,即`script.js?v = 1.2`.(或者,如果您没有跟踪版本,只需使用文件最后修改时间,这更容易做到).不确定这是不是以前的评论者的意思! (51认同)
  • 这是一个相当不错的解决方案,甚至可以由您的构建系统自动化(并且应该是).例如,Stackoverflow使用这种方法. (8认同)
  • 现在正在使用GET参数. (7认同)
  • 每个人如何通过版本控制来做到这一点?看起来真的很痛苦. (5认同)
  • @Doin,我简要测试了该技术,它似乎阻止了 Firefox 和 Chrome 完全缓存文件。 (2认同)
  • @Doin,我使用在 IIS 7.5 上运行的 ASP.NET 网站进行了测试,该网站提供静态 PNG 图像文件。我使用了 Fiddler4,从内存中发现,当查询字符串存在时,服务器总是返回“200”,否则它会在 Firefox 和 Chrome 中返回“304”。IE很好。问题也可能出在 IIS 或 ASP.NET 上,所以我可能是错的。 (2认同)
  • 这适用于除 chrome 之外的所有浏览器 (2认同)

Sam*_*son 97

查看缓存控件过期 META标记.

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

  • 这对于已经缓存的情况没有多大帮助 - 因为它的缓存,服务器将不会被查询,因此无法使用no-cache进行响应.此外,该元标记确实不应该被使用,正如笔记所说,它将打破网络缓存. (41认同)
  • 为您的第二个解决方案+1.我有这个问题,只有在一些管理员进行更新后第一次清除缓存.这种方法应解决这个问题 (4认同)

rsp*_*rsp 73

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);
Run Code Online (Sandbox Code Playgroud)

有关详细信息,另请参阅在Mozilla Developer Network上使用应用程序缓存.

2016年更新

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

目前,截至2016年7月,HTML标准,第7.9节,脱机Web应用程序包含弃用警告:

此功能正在从Web平台中删除.(这是一个需要很多年才能完成的漫长过程.)目前使用任何脱机Web应用程序功能都是非常不鼓励的.请改用服务工作者.

使用我在2012年引用的Mozilla Developer Network上的应用程序缓存也是如此:

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

另请参见错误1204581 - 如果启用了service worker fetch拦截,则为AppCache添加弃用通知.

  • 那么,截至2017年的当前推荐是什么? (50认同)
  • 2017年:使用服务工作者. (3认同)
  • 2021 年有什么建议吗? (3认同)

Pek*_*ica 27

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

确保所有浏览器都不会缓存网页.

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

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

myimage.gif?random=1923849839
Run Code Online (Sandbox Code Playgroud)

  • 那真的取决于情况,不是吗?如果您正在编程CMS并且需要确保所有更改的资源都已正确更新,则有时无法绕过这两个选项之一. (8认同)
  • 正确地对文件进行版本控制确实更好。这是相当大的带宽浪费,而且可能更重要的是,这会使您的网站速度大大降低。 (2认同)

Pau*_*nis 14

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

/Content/css/Site.css?version={FileVersionNumber}
Run Code Online (Sandbox Code Playgroud)

这是ASP.NET MVC示例.

<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
Run Code Online (Sandbox Code Playgroud)

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

  • 我发现这会阻止 Firefox 和 Chrome 完全缓存内容。 (2认同)

Woj*_*rek 9

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

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

    <html manifest="cache.manifest">
    
    Run Code Online (Sandbox Code Playgroud)
  2. <head>包含脚本更新缓存的部分中:

    <script type="text/javascript" src="update_cache.js"></script>
    
    Run Code Online (Sandbox Code Playgroud)
  3. <body>第一节中我插入了onload函数:

    <body onload="checkForUpdate()">
    
    Run Code Online (Sandbox Code Playgroud)
  4. cache.manifest我已经把所有的文件我想缓存.现在重要的是,只要每次更新"版本"注释,它都适用于我的情况(Apache).也可以选择在名称末尾用"?ver = 001"命名文件,但不需要.更改只会# version 1.01触发缓存更新事件.

    CACHE MANIFEST
    # version 1.01
    style.css
    imgs/logo.png
    #all other files
    
    Run Code Online (Sandbox Code Playgroud)

    重要的是在index.html中包含1.,2.和3.点.除此以外

    GET http://foo.bar/resource.ext net::ERR_FAILED
    
    Run Code Online (Sandbox Code Playgroud)

    因为每个"子"文件在页面已经缓存时尝试缓存页面,都会发生这种情况.

  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();
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在您只需更改文件,在清单中您必须更新版本注释.现在访问index.html页面将更新缓存.

解决方案的部分不是我的,但我通过互联网找到它们并将它们放在一起以便它起作用.

  • @ShwetaGulati这是因为浏览器自动缓存一些文件以使页面加载更快。这是默认行为,仅依赖于浏览器,因此您无法以任何方式设置它。特别是js文件在浏览器的范围内,因为它们通常在网站的所有页面上使用,所以缓存它们是明智的。除了将所有文件名写入清单文件中之外,没有其他方法可以缓存所有文件。如果你找到了,请告诉我,因为我也需要它:) (2认同)
  • 为了供将来参考,浏览器已删除/取消/禁用此功能。 (2认同)

tru*_*ted 9

2023年以后

在撰写本文时,大多数主流 Web 浏览器(Safari 除外)都支持Clear-Site-DataHTTP 标头 [ MDN 参考]。

要指示客户端 Web 浏览器清除网站域和子域的浏览器缓存,请在服务器的 HTTP 响应中设置以下标头:

Clear-Site-Data: "cache"
Run Code Online (Sandbox Code Playgroud)

或者,以下标头可能会更好地支持跨浏览器,但除了浏览器缓存之外,它还会清除其他网站数据,例如 localStorage 和 cookie。

Clear-Site-Data: "*"
Run Code Online (Sandbox Code Playgroud)


zee*_*han 7

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

<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
Run Code Online (Sandbox Code Playgroud)

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

<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
Run Code Online (Sandbox Code Playgroud)

  • 这根本不优雅,它会使网站每次浪费大量时间下载资源时重新加载图像,更好的解决方案是使用[filesize](http://php.net/manual/en/function. filesize.php)而不是随机数,这将使缓存仅在文件实际更改时重新生效 (28认同)
  • 或者图像字节的哈希值 (7认同)
  • <img rel="nofollow noreferrer" src ="/ photos/userid_73.jpg?modified = <?= filemtime("/ photos/userid_73.jpg")?>"会更有用! (3认同)

小智 5

很多答案都没有抓住要点——大多数开发人员都清楚关闭缓存效率低下。然而,在许多常见情况下,效率并不重要,并且默认缓存行为被严重破坏。

其中包括嵌套的迭代脚本测试(最重要的!)和损坏的第三方软件解决方法。此处给出的解决方案都不足以解决此类常见情况。大多数网络浏览器的缓存过于激进,并且没有提供避免这些问题的明智方法。


nPc*_*omp 5

将 URL 更新为以下内容对我有用:

/custom.js?id=1

通过在之后添加唯一的编号?id=并针对新的更改递增该编号,用户无需按CTRL + F5刷新缓存。或者,您可以在之后附加当前时间或 Epoch 的哈希或字符串版本?id=

就像是?id=1520606295