【问题标题】:Force refresh of cached CSS data强制刷新缓存的 CSS 数据
【发布时间】:2011-04-21 16:58:30
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您可以找到一个热键列表来强制浏览器执行“硬重置”,这将清除下面的缓存。 en.wikipedia.org/wiki/…

标签: css caching


【解决方案1】:

有几件事情需要考虑,并且有多种方法可以解决这个问题。一、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            |
+---------------------+--------------------+-------------------------+

然而,请记住浏览器和网络服务器并不总是按照我们预期的方式运行。一个著名的例子:in 2012 mobile Safari began caching POST requests。开发者不高兴。

查询字符串

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

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

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

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

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

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

@{
    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 标头以最大限度地发挥缓存的优势

【讨论】:

  • 啊我喜欢这个想法
  • 把 TLDR 放在第一位 ^^ :)
【解决方案2】:

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

另一种解决方案是:

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

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

【讨论】:

    【解决方案3】:

    请先阅读 Tim Medora 的答案,因为这是一篇知识渊博且非常努力的帖子。

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

    所以我使用查询字符串技术和 PHP filemtime(),它将返回最后修改的时间戳。

    该函数返回文件数据块被写入的时间,即文件内容发生变化的时间。

    在我的 webapps 中,我使用 config.php 文件来存储我的设置,所以在这里我将创建一个像这样的变量:

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

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

    <link rel="stylesheet" type="text/css" media="all" href="<?php echo $siteCSS?>" />
    

    到目前为止,这在 PHP/IIS 上对我来说非常有用。

    【讨论】:

    • 即使在使用版本控制时,这也是确保更改的好方法。我喜欢它,因为它仍在开发中工作。
    【解决方案4】:

    你也许可以在 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-17
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多