强制刷新缓存的CSS数据

Mic*_*rds 37 css caching

是否有可能强制浏览器刷新缓存的CSS?

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

现在我们需要对CSS进行一些重大更新; 但是,缓存CSS的浏览器将在几天内不会收到新的CSS,从而导致渲染问题.

有没有办法强制刷新CSS或者我们最好只选择版本特定的CSS URL?

Tim*_*ora 53

有几件事需要考虑,有多种方法可以解决这个问题.一,规格

我们想要完成什么?

理想情况下,修改后的资源将在第一次请求时无条件地获取,然后从本地缓存中检索,直到它到期而没有后续服务器交互.

观察到的缓存行为

跟踪不同的排列可能有点令人困惑,所以我创建了下表.这些观察是通过向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            |
+---------------------+--------------------+-------------------------+
Run Code Online (Sandbox Code Playgroud)

但是,请记住,浏览器和Web服务器并不总是按照我们期望的方式运行.一个着名的例子:2012年,移动Safari开始缓存POST请求.开发人员并不高兴.

请求参数

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

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

将随机参数附加到HTML中包含的CSS URL的末尾将强制执行新请求,服务器应响应HTTP 200(而不是304,即使它尚未被修改).

<link href="normalfile.css?random=@Environment.TickCount" />
Run Code Online (Sandbox Code Playgroud)

当然,如果我们随每个请求随机化查询字符串,这将完全打败缓存.对于生产应用来说,这很少/永远不可取.

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

@{
    var assembly = Assembly.GetEntryAssembly();
    var name = assembly.GetName();
    var version = name.Version;
}

<link href="normalfile.css?build=@version.MinorRevision" />
Run Code Online (Sandbox Code Playgroud)

这将在用户代理第一次遇到URL时产生新请求,但后续请求将主要返回304.这仍然会导致请求,但至少不提供整个文件.

路径修改

更好的解决方案是创建新路径.只需稍加努力,就可以自动执行此过程,以使用版本号(或其他一致的标识符)重写路径.

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

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

当然,最简单(不一定是最快或最好)的方法是只重命名每个版本的文件并引用link标签中的更新路径.

TLDR

  • 更改文件名或查询字符串
  • 使用每个版本仅发生一次的更改
  • 文件重命名比查询字符串更改更可取
  • 始终设置HTTP标头以最大化缓存的好处

  • 把TLDR放在第一位^^ :) (9认同)

And*_*Gee 7

我认为重命名CSS文件是一个好主意.它可能不适合所有应用程序,但它将确保用户只需加载一次CSS文件.添加随机字符串将确保他们每次都必须下载它.javascript方法和上面的apache方法也是如此.有时简单的答案可能是最有效的.

另一种解决方案是

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

这会将最大缓存时间限制为1天或86400秒.