问题描述
我注意到一些浏览器(特别是Firefox和Opera)非常热衷于使用 .css 和 .js 文件的缓存副本,即使在浏览器会话之间也是如此.当您更新这些文件之一而用户的浏览器继续使用缓存的副本时,这会导致出现问题.
I have noticed that some browsers (in particular, Firefox and Opera) are very zealous in using cached copies of .css and .js files, even between browser sessions. This leads to a problem when you update one of these files but the user's browser keeps on using the cached copy.
问题是:强迫用户的浏览器在文件更改后重新加载文件的最优雅的方法是什么?
The question is: what is the most elegant way of forcing the user's browser to reload the file when it has changed?
理想情况下,该解决方案不会强制浏览器在每次访问页面时重新加载文件.我将发布自己的解决方案作为答案,但是我很好奇是否有人有更好的解决方案,我将让您的投票决定.
Ideally, the solution would not force the browser to reload the file on every visit to the page. I will post my own solution as an answer, but I am curious if anyone has a better solution and I'll let your votes decide.
更新:
在允许了一段时间的讨论后,我发现 John Millikin 和 da5id 的建议很有用.事实证明有一个术语:自动版本.
After allowing discussion here for a while, I have found John Millikin and da5id's suggestion to be useful. It turns out there is a term for this: auto-versioning.
我在下面发布了一个新答案,该答案是我原来的解决方案和约翰的建议的结合.
I have posted a new answer below which is a combination of my original solution and John's suggestion.
SCdF 提出的另一种想法是将假查询字符串附加到文件中. ( pi 提交了一些将时间戳自动用作伪造查询字符串的Python代码.)但是,关于浏览器是否将使用查询字符串缓存文件存在一些讨论. (请记住,我们希望浏览器缓存文件并在以后的访问中使用它.我们只希望它在更改后再次获取该文件.)
Another idea that was suggested by SCdF would be to append a bogus query string to the file. (Some Python code to automatically use the timestamp as a bogus query string was submitted by pi.). However, there is some discussion as to whether or not the browser would cache a file with a query string. (Remember, we want the browser to cache the file and use it on future visits. We only want it to fetch the file again when it has changed.)
由于尚不清楚伪查询字符串会发生什么,因此我不接受该答案.
Since it is not clear what happens with a bogus query string, I am not accepting that answer.
推荐答案
更新:已重写以合并 John Millikin 和 da5id 的建议.该解决方案是用PHP编写的,但应易于适应其他语言.
Update: Rewritten to incorporate suggestions from John Millikin and da5id. This solution is written in PHP, but should be easily adapted to other languages.
更新2:结合了 Nick Johnson 的评论,即原始的.htaccess
正则表达式可能会导致json-1.3.js
之类的文件出现问题.解决方案是仅在末尾恰好有10位数字时才重写. (因为10位数字覆盖了从9/9/2001到11/20/2286的所有时间戳.)
Update 2: Incorporating comments from Nick Johnson that the original .htaccess
regex can cause problems with files like json-1.3.js
. Solution is to only rewrite if there are exactly 10 digits at the end. (Because 10 digits covers all timestamps from 9/9/2001 to 11/20/2286.)
首先,我们在.htaccess中使用以下重写规则:
First, we use the following rewrite rule in .htaccess:
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
现在,我们编写以下PHP函数:
Now, we write the following PHP function:
/**
* Given a file, i.e. /css/base.css, replaces it with a string containing the
* file's mtime, i.e. /css/base.1221534296.css.
*
* @param $file The file to be loaded. Must be an absolute path (i.e.
* starting with slash).
*/
function auto_version($file)
{
if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file;
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}
现在,无论您在哪里包含CSS,都可以通过以下方式进行更改:
Now, wherever you include your CSS, change it from this:
<link rel="stylesheet" href="/css/base.css" type="text/css" />
对此:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
通过这种方式,您无需再次修改link标签,并且用户将始终看到最新的CSS.浏览器将能够缓存CSS文件,但是当您对CSS进行任何更改时,浏览器会将其视为新的URL,因此它将不使用缓存的副本.
This way, you never have to modify the link tag again, and the user will always see the latest CSS. The browser will be able to cache the CSS file, but when you make any changes to your CSS the browser will see this as a new URL, so it won't use the cached copy.
这也可以用于图像,图标和JavaScript.基本上任何不是动态生成的.
This can also work with images, favicons, and JavaScript. Basically anything that is not dynamically generated.
这篇关于如何强制浏览器重新加载缓存的CSS/JS文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!