强制刷新caching的CSS数据

是否有可能强制浏览器新鲜的caching的CSS?

这不像每个请求那么简单。 我们有一个网站,有一段时间稳定的CSS。

现在我们需要对CSS做一些重大更新; 但是,已经cachingCSS的浏览器在接下来的几天内将不会收到新的CSS,从而导致渲染问题。

有没有办法强制刷新CSS,或者我们更好的select版本特定的CSSurl?

有几件事情需要考虑和多种方法来解决这个问题。 首先, 规格

我们想要完成什么?

理想情况下,修改后的资源将在第一次被请求时被无条件地取回,然后从本地caching中检索,直到失效,并且没有后续的服务器交互。

观察caching行为

跟踪不同的排列可能有点混乱,所以我创build了下表。 这些观察是通过向Chrome提出针对IIS的请求并观察开发者控制台中的响应/行为而产生的。

在任何情况下,一个新的URL将导致HTTP 200.重要的是随后的请求会发生什么。

+---------------------+--------------------+-------------------------+ | Type | Cache Headers | Observed Result | +---------------------+--------------------+-------------------------+ | Static filename | Expiration +1 Year | Taken from cache | | Static filename | Expire immediately | Never caches | | Static filename | None | HTTP 304 (not modified) | | | | | | Static query string | Expiration +1 Year | HTTP 304 (not modified) | | Static query string | Expire immediately | HTTP 304 (not modified) | | Static query string | None | HTTP 304 (not modified) | | | | | | Random query string | Expiration +1 Year | Never caches | | Random query string | Expire immediately | Never caches | | Random query string | None | Never caches | +---------------------+--------------------+-------------------------+ 

但是请记住,浏览器和Web服务器并不总是按照我们的预期行事。 一个着名的例子: 在2012年移动Safari开始cachingPOST请求 。 开发商不高兴。

查询string

ASP.Net MVC Razor语法中的示例,但几乎适用于任何服务器处理语言。

…因为一些应用程序传统上使用带有查询URL(在rel_path部分中包含“?”)的GET和HEAD来执行带有明显副作用的操作,所以caching不应该将对这种URI的响应视为新鲜,除非服务器提供明确的到期时间。 这特别意味着HTTP / 1.0服务器对这些URI的响应不应该从caching中获取。

将一个随机参数附加到包含在HTML中的CSS URL的末尾将会强制一个新的请求,并且服务器应该以HTTP 200响应(不是304,即使它没有被修改)。

 <link href="normalfile.css?random=@Environment.TickCount" /> 

当然,如果我们随机查询string与每个请求,这将完全击败caching。 对于生产应用来说,这是很less/不可取的。

如果只维护几个URL,则可以手动修改它们以包含内部版本号或date:

 @{ var assembly = Assembly.GetEntryAssembly(); var name = assembly.GetName(); var version = name.Version; } <link href="normalfile.css?build=@version.MinorRevision" /> 

这将在用户代理第一次遇到URL时引发新请求,但后续请求将主要返回304。 这仍然会导致一个请求,但至less整个文件没有送达。

path修改

更好的解决scheme是创build一个新的path。 通过一点努力,这个过程就可以自动地用一个版本号(或其他一致的标识符)重写path。

这个答案显示了非Microsoft平台的一些简单而优雅的选项。

微软的开发人员可以使用一个拦截给定文件types的所有请求的HTTP模块,或者可能利用一个MVC路由/控制器组合来提供正确的文件(我还没有看到这样做,但我相信这是可行的)。

当然,最简单的(不一定是最快或者最好的)方法就是对每个版本重新命名相关文件,并引用link标签中的更新path。

TLDR

  • 更改文件名或查询string
  • 使用每次发布只发生一次的更改
  • 文件重命名优于查询string更改
  • 始终设置HTTP标头以最大化caching的好处

我认为重命名CSS文件是一个更好的主意。 它可能不适合所有的应用程序,但它将确保用户只需要加载一次CSS文件。 添加一个随机string到最后将确保他们不得不每次下载它。 上面的javascript方法和apache方法也是一样的。 有时候,简单的答案可能是最有效的。

另一个解决scheme是

 <FilesMatch "\.(js|css)$"> Header set Cache-Control "max-age=86400, public" </FilesMatch> 

这将最大caching时间限制为1天或86400秒。

Yu也许可以在apache上做…

 <FilesMatch "\.(html|htm|js|css)$"> FileETag None <IfModule mod_headers.c> Header unset ETag Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT" </IfModule> </FilesMatch>