在关于 CSS 缓存文章 的 许多精彩评论 中,我学到了很多东西,因此我想澄清一些误解并重点介绍其他用户分享的一些很棒技巧。
- 是**浏览器**执行缓存,但**服务器**可以对此有所决定。 许多浏览器首先会询问服务器是否需要重新下载 CSS,服务器会做出响应。 有时服务器会以 304(未修改)响应,这将告诉浏览器只需使用其自己的缓存副本。 显然,如果您更改了服务器上的 CSS 并几乎立即刷新浏览器,服务器可能尚未赶上并会以 304 响应,而您的浏览器将使用其缓存副本。(感谢 Eric)
- 您可以更改服务器设置(如果您使用的是 Apache)以在 1 秒后“过期” CSS 文件。 参见第二条评论。 这将实现与时间戳相同的效果,因为浏览器会始终告诉浏览器它应该下载最新的 CSS。(感谢 Joshua)
- 如果您使用的是任何类型的版本控制软件,在 CSS 链接的末尾添加版本信息可能是处理此问题的一个更明智的方法。(感谢 August)
- 而不是将确切的日期和时间附加到 CSS 链接的末尾,将文件最后一次修改的日期和时间附加到末尾更明智。 尝试以下方法:**echo filectime(’/path/to/style.css’);** 这也返回时间戳而不是“人类可读”日期,这将消除 URL 链接中的空格。(感谢......所有人!)
- 请记住,您可以在大多数浏览器中使用 SHIFT-Refresh 强制它重新下载所需的所有文件。 这很容易向您的客户解释!(感谢 Paul)
在网站页面之间切换时,许多浏览器根本不会返回服务器获取 CSS 文件,尽管大多数在按下刷新时都会发出请求。
将查询字符串附加到 CSS 文件将阻止浏览器使用缓存,但这不应该在实时网站上使用。 即使查询字符串保持不变,某些浏览器也会始终从服务器获取最新副本。 我相信 Opera 和 Safari 这样做,根据 http 规范。
来自 ftp://ftp.isi.edu/in-notes/rfc2616.txt
—
我们注意到此规则的一个例外:由于一些应用程序传统上使用带有查询 URL(在 rel_path 部分中包含“?”)的 GET 和 HEAD 来执行具有重大副作用的操作,因此缓存**绝不能**将对这些 URI 的响应视为新鲜,除非服务器提供明确的过期时间。 这具体意味着来自 HTTP/1.0 服务器的此类 URI 的响应**不应该**从缓存中获取。
—
最佳方法是在 CSS 文件上设置一个遥远的未来过期时间,并在数据更改时更改 URL,而不使用查询字符串。 您可以使用 mod_rewrite 或通过实际更改 CSS 文件的名称来实现这一点。
css/style1.css
…进行更改…
css/style2.css
文件名的唯一部分可以是文件修改日期的时间戳,mod_rewrite 将使 style\d+.css 指向 style.css。
这样,用户始终能够获得您 CSS 的最新版本,而不会将缓存抛到窗外。
Jake。
关于浏览器和服务器之间的交互的说明,Jake 正确指出,如果文件具有 EXPIRE 标头为 -1 或未来某个日期,则浏览器并不总是向服务器请求新的样式表(尤其是 Opera)。
在 1 秒后使 CSS 文件“过期”是确保用户 CSS 最新的一种方法,还有许多其他标头,例如 PRAGMA=no-cache 等等。
我发现的最佳方法之一来自雅虎的建议:将 ETag 标头设置为文件名 + 文件时间。 我无法告诉您配置服务器以执行此操作的所有方法,但现在您有了要谷歌搜索的内容以及一个起点。
希望有帮助! 感谢您的更新,Chris!
shift-refresh 完全让我的早晨变得美好。 我一直在尝试弄清楚如何做到这一点!
对于所有那些喜欢快捷键的人:CTRL + F5 也会强制下载网页上的所有文件。
我一直在开发一种类似的东西,用于 Javascript 文件。 最近,我完成了我的用于“Zend Framework”的 Javascript 聚合器,它为每个 Javascript 文件组合编译一个单独的文件。
现在,这有什么意思? 用于检查组合是否已编译并缓存的标识符是所有文件的组合主体的 md5 校验和。 这样,如果一个文件的内容发生更改,则密钥也会更改,并且服务器会发送一个新文件,否则不会再次请求该文件。
我目前也在尝试为 CSS 文件执行类似的操作,我会努力让你们了解进展。
我忘记提到的还有一点是,md5 校验和是加载的文件名,而不是 5 个单独的文件。
说真的,伙计们,我个人倾向于使用以下方式重命名文件:
现在我甚至不在代码中使用 v 变量,我甚至都不查看 get 参数以检查它是否存在。 但是浏览器!哦,它认为这是一个全新的维度需要探索,并且完全忘记了缓存 :)
这样,您也始终了解您所处的文件版本。 我曾经创建了一个引擎,它根据文件系统中发生的更改来操作“v”的值。 就像一个基本的 svn,因为它无损。 :) 祝一切顺利