强制刷新缓存的CSS数据

时间:2010-10-06 08:33:47

标签: css caching

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

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

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

有没有办法强制刷新CSS,还是我们最好选择特定版本的CSS网址?

4 个答案:

答案 0 :(得分:53)

有几件事需要考虑,有多种方法可以解决这个问题。首先,the spec

我们想要完成什么?

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

观察到的缓存行为

跟踪不同的排列可能有点令人困惑,所以我创建了下表。这些观察是通过向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服务器的行为并不总是如我们所期望的那样。一个着名的例子:in 2012 mobile Safari began caching POST requests。开发人员并不高兴。

查询字符串

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

  

...因为一些应用程序传统上使用GET和HEAD   查询URL(在rel_path部分中包含“?”的URL)要执行   有明显副作用的手术,缓存不得治疗   除非服务器提供明确的,否则对这些URI的响应为新鲜   到期时间。这特别意味着来自HTTP / 1.0的响应   这些URI的服务器不应该从缓存中获取。

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

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

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

如果您只维护一些网址,则可以手动修改它们以包含内部版本号或日期:

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

<link href="normalfile.css?build=@version.MinorRevision" />

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

路径修改

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

This answer为非Microsoft平台显示了一些简单而优雅的选项。

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

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

TLDR

  • 更改文件名或查询字符串
  • 使用每次发布仅发生一次的更改
  • 文件重命名优于查询字符串更改
  • 始终设置HTTP标头以最大限度地发挥缓存的好处

答案 1 :(得分:7)

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

另一种解决方案是:

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

这会将最大缓存期限限制为1天或86400秒。

答案 2 :(得分:0)

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>

答案 3 :(得分:0)

请先阅读蒂姆·梅多拉(Tim Medora)的答案,因为这是一篇非常博学且努力的文章。

现在,我将告诉您如何在PHP中进行操作。我不想打扰传统的版本控制或试图维护1000多个页面,但是我想确保用户始终获得我的CSS的最新版本并将其缓存。

因此,我使用查询字符串技术和PHP filemtime()来返回最后修改的时间戳。

  

此函数返回写入文件数据块的时间,即文件内容被更改的时间。

在我的Web应用程序中,我使用config.php文件存储我的设置,因此在这里,我将像这样创建一个变量:

renderLabel = (date) => {
  console.log(date.isValid());
  if (date.isValid()) {
    return date.format("DD/MM/YYYY");
  } else {
    return '';
  }
}

,然后在我的所有页面中,我将像这样引用我的CSS:

$siteCSS = "/css/standard.css?" .filemtime($_SERVER['DOCUMENT_ROOT']. "/css/standard.css");

到目前为止,在PHP / IIS上,这对我来说一直很好。