使用 ?version=XXX 刷新缓存中的 CSS 文件

Posted

技术标签:

【中文标题】使用 ?version=XXX 刷新缓存中的 CSS 文件【英文标题】:Refresh CSS file in cache with ?version=XXX 【发布时间】:2012-12-08 06:09:40 【问题描述】:

为了刷新缓存中的 CSS 文件,我经常使用 file.css?version=DDMMYYYY 技巧。 但是,我对这种方法有疑问。

我正在开发一个旧的外联网。 所有页面都使用相同的 CSS 文件。 Extranet 没有任何模板文件,并且这个 css 包含在 Extranet 的每个页面中。 我需要为所有 Extranet 页面刷新这个 css 文件。

我的问题是: 我想在登录页面上使用 file.css?version=DDMMYYYY 技巧。 其他页面仍将包含 file.css(没有 ?version 部分)

如果用户进入登录页面,他将收到新版本的 css 文件。 但是其他页面将使用哪个版本?旧版本(file.css)还是新版本(file.css?version=DDMMYYYY)?

也就是说,当用户进入登录页面时,哪些文件会在他的缓存中:

file.css 和 file.css?version=DDMMYYYY 只有file.css,更新到新版本

对于这个初学者问题,我很抱歉,但我自己测试时遇到了一些困难。

感谢您的帮助!

【问题讨论】:

我 99% 确定这将是较新的版本,因为它们都具有相同的实际真实文件名。你不能测试一下看看会发生什么吗? 出于好奇 - 为什么需要像这样刷新 CSS?它经常变化吗?当它发生时 - 浏览器不应该自动检测到变化吗? @Trekstuff 并非总是如此。取决于 HTTP 标头中包含的信息以及文件是否带有过期日期等标记。 为什么不到处使用?version=DDMMYYYY?只需确保使用 css 文件的实际修改日期或静态版本号(不是当前日期)。 答案取决于您的服务器使用/用于 CSS 文件的过期标头。 【参考方案1】:

当文件被缓存时,它将带有完整的 url,包括 ? 和它后面的东西。缓存标头由服务器提供并由浏览器遵守。

基本上

file.css?version=DDMMYYYY 和 文件.css

对于浏览器来说是 2 个单独的文件,没有任何连接。

我对您的建议是在所有页面上一致地使用新网址。

【讨论】:

【参考方案2】:

这不起作用,它们的缓存方式不同,虽然file.cssfile.css?version=DDMMYYYY 是文件系统中的同一个文件,但它们是不同的URI,服务器响应可能完全不同......所以,file.css可以在使用file.css?version=DDMMYYYY 获取正确文件的同时从缓存中加载旧文件。

防止这种情况的一种方法是完全禁用缓存,这会导致每次加载页面时都会下载 css 文件,但会立即更新,或者您可以将缓存设置为在短时间内过期,比如 10 分钟,2 小时,所以它会每 10 分钟/2 小时下载一次......

如果您使用启用了 htaccess 的 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>

【讨论】:

感谢您的回复,我会联系我的系统管理员以查看是否可以更改 apache conf 中的某些内容。如果没有可能,我会使用你的 htaccess 技巧 我认为您的 htaccess 技巧不会奏效。如果该文件始终在缓存中,则不会为该文件联系服务器,并且不会执行您的 htaccess。仅当我们不希望缓存文件时才有用,但它不会刷新浏览器缓存中的文件 @Guigoz 当然,您需要清除缓存一次或等到浏览器注意到 Etag 更改。但是在使用新标头再次加载后,它将以更短的到期时间进行缓存。当必须立即重新下载文件而无需用户与浏览器交互并且文件已经缓存了很长的过期时间时,除了更改 URI 之外别无他法。 @Guigoz but it will not refresh the file in the browser cache 缓存头用于控制浏览器缓存【参考方案3】:

在我的项目中,我还使用 ?version 方法强制浏览器获取新版本的 CSS 文件。 而不是使用 ?version=DDMMYYYY 我建议使用 filemtime()。

例子:

<link rel="stylesheet" href="css/custom.css?<?php=filemtime('css/custom.css')?>" type="text/css" media="screen" />

函数 filemtime() 获取文件修改时间,因此当 CSS 文件更改时,浏览器将获取新版本的 CSS。如果文件未更改,则时间保持不变,浏览器使用文件的缓存版本。

【讨论】:

以上是关于使用 ?version=XXX 刷新缓存中的 CSS 文件的主要内容,如果未能解决你的问题,请参考以下文章

IDEA Cannot resolve method ‘xxx‘问题解决IDEA刷新缓存重启

如何缓存和刷新托管标识令牌

yii使用之缓存

InnoDB后台线程

转载web网站css,js更新后客户浏览器缓存问题,需要刷新才能正常展示的解决办法

刷新 django 中的 urls.py 缓存