【问题标题】:Forcing the browser to reload css when it has been updated强制浏览器在更新后重新加载 css
【发布时间】:2012-04-27 09:32:43
【问题描述】:

当我在服务器上更新一个 css 文件时,许多客户端浏览器会在相当长的一段时间内继续使用旧的缓存 css 文件加载页面。

在搜索了许多帖子并将不同的想法放在一起后,我想出了似乎是最简单和最便宜的方法。

在链接任何 css 文件的地方,在 href 后面加上文件最后修改日期的时间戳,如下所示:

<link rel="stylesheet" type="text/css" href="main.css?t=<?=filemtime('main.css')?>" />

我使用的是CakePHP,所以我在布局文件中的操作是这样的:

  <? $t = filemtime(CSS . 'main.css'); ?>
  <?=$html->css("schedule.css?t={$t}") ?>

所以指向css文件的链接末尾有一个额外的标签,但只要文件没有被修改,它就保持不变。这意味着浏览器将能够像往常一样缓存它。但是,一旦文件被修改,链接就会改变,浏览器不会错过任何一个节拍。

仍然使用这种方法,人们会因为将某些东西用于非预期用途而感到有点肮脏。正在发送的“消息”没有任何用处,因为消息的内容很重要,除了识别它的存在。

这是我的问题:

  1. 能否承认存在客户端从浏览器缓存中看到带有过期样式表(或 JavaScript)的修订 HTML 的风险?
  2. 这是破解还是合法的解决方案?
  3. 有更好的解决方案吗?

【问题讨论】:

  • 第二个问题:不,不是。事实上,它更像是一种约定(如果还没有的话)。
  • 对于支持它的设备,您可以在清单文件上创建和管理时间(参见教程:html5rocks.com/en/tutorials/appcache/beginner)。然而,附加的时间戳被广泛使用,老实说可能是一个更好的解决方案。

标签: php css cakephp caching browser-state


【解决方案1】:

我认为您的方法没有任何问题。更常见的是,这称为缓存破坏或缓存失效。

但是,由于您使用的 URL 为:http://site.com/assets/mystyle.css?29320202020,因此 CDN 可能存在问题。 CDN 将看到 GET 参数并认为它是一个动态请求,因此它会向您的服务器请求文件,这违背了在 CDN 中拥有缓存副本的目的。

我这样做的原因是我在我的文件名中包含了缓存破坏参数:http://site.com/assets/mystyle.2390202202.css。我正在使用出色的 Assetic library 来执行此操作,并且刚刚编写了一些简单的代码,以便我的模板知道它需要 mystyle.cssmystyle.2390202202.css 由 Assetic 动态生成并插入到模板中。

这种方法应该让您在处理 CDN 的同时获得缓存破坏功能。


其他可能的解决方案:

  • ETags:浏览器会向服务器发送一个带有 ETag 的请求(可以认为是文件的哈希),如果文件没有改变,服务器会返回一个未修改的 header 响应.缺点:仍然需要发出 HTTP 请求。

  • 设置过期头:服务器会告诉浏览器文件将在某个日期过期,如果还不是那个日期,浏览器将不会向服务器请求副本并使用其本地缓存副本。缺点:如果服务器上的文件在日期之前发生变化,浏览器的用户将需要手动进行硬刷新。

这就是为什么我更喜欢只使用缓存破坏参数的原因:我可以将文件的 expires 标头设置为 5 年后过期。并且浏览器不应该对该文件发出 http 请求,除非我更新文件并更改缓存清除参数。

【讨论】:

  • +1 表示“缓存破坏”一词。这有助于搜索谷歌。查询字符串是否会导致浏览器每次都下载文件?我会用它做一些测试。我对接受这个答案犹豫不决,因为我仍然认为应该有更好的方法告诉浏览器该文件有新版本,而不是使用 php 框架重命名它。
  • 用其他可能的解决方案更新了我的答案,但我觉得缓存破坏可能是最好/最有效的。 :)
【解决方案2】:

CakePHP 有一个非常简单易用的解决方案。只需取消注释此行:

//Configure::write('Asset.timestamp', true);

来自core.php

根据该文件,这将

将带有最后修改时间的时间戳应用于静态资产(js、 CSS,图像)。将附加一个包含时间的查询字符串参数 文件被修改。这对于使浏览器缓存无效。

这非常简单,并且大部分时间都可以使用,但它并非万无一失。大多数代理不使用“?”缓存资源。在 URL 中,所以如果你想解决这些情况,你应该实现一个更复杂的解决方案,就像 phpdev 建议的那样。

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 2012-11-04
    • 2015-01-05
    • 2013-04-02
    • 2010-09-10
    • 2013-07-27
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多