63

CSS 和 Javascript 文件不会经常更改,因此我希望它们被 Web 浏览器缓存。但我也希望 Web 浏览器能够查看对这些文件所做的更改,而无需用户清除浏览器缓存。还需要一个与 Subversion 等版本控制系统配合良好的解决方案。


我见过的一些解决方案涉及以查询字符串的形式在文件末尾添加版本号。

可以使用 SVN 修订号为您自动执行此操作:ASP.NET Display SVN Revision Number

你能指定如何包含另一个文件的修订变量吗?那就是在 HTML 文件中,我可以在 CSS 或 Javascript 文件的 URL 中包含修订号。

Subversion 书中,它谈到了修订:“此关键字描述了该文件在存储库中更改的最后一个已知修订”。

Firefox 还允许按CTRL+R重新加载特定页面上的所有内容。

为了澄清,我正在寻找不需要用户做任何事情的解决方案。

4

5 回答 5

29

我发现如果您将文件的最后修改时间戳附加到 URL 的末尾,浏览器将在修改文件时请求文件。例如在 PHP 中:

function urlmtime($url) {
   $parsed_url = parse_url($url);
   $path = $parsed_url['path'];

   if ($path[0] == "/") {
       $filename = $_SERVER['DOCUMENT_ROOT'] . "/" . $path;
   } else {
       $filename = $path;
   }

   if (!file_exists($filename)) {
       // If not a file then use the current time
       $lastModified = date('YmdHis');
   } else {
       $lastModified = date('YmdHis', filemtime($filename));
   }

   if (strpos($url, '?') === false) {
       $url .= '?ts=' . $lastModified;
   } else {
       $url .= '&ts=' . $lastModified;
   }

   return $url;
}

function include_css($css_url, $media='all') {
   // According to Yahoo, using link allows for progressive 
   // rendering in IE where as @import url($css_url) does not
   echo '<link rel="stylesheet" type="text/css" media="' .
        $media . '" href="' . urlmtime($css_url) . '">'."\n";
}

function include_javascript($javascript_url) {
   echo '<script type="text/javascript" src="' . urlmtime($javascript_url) .
        '"></script>'."\n";
}
于 2008-08-06T09:41:02.353 回答
10

我见过的一些解决方案涉及以查询字符串的形式在文件末尾添加版本号。

<script type="text/javascript" src="funkycode.js?v1">

您可以使用 SVN 修订号来自动执行此操作方法是在您的 html 文件中的 v1 出现在上面的位置之后包含单词LastChangedRevision 。您还必须设置您的存储库来执行此操作。

我希望这进一步澄清了我的答案?

Firefox 还允许按CTRL+R重新加载特定页面上的所有内容。

于 2008-08-06T09:52:01.347 回答
8

在我看来,最好将版本号作为文件本身的一部分,例如myscript.1.2.3.js. 您可以将您的网络服务器设置为永久缓存此文件,并在您有新版本时添加一个新的 js 文件。

于 2008-08-06T21:33:14.473 回答
6

当您发布新版本的 CSS 或 JS 库时,会导致以下情况发生:

  1. 修改文件名以包含唯一的版本字符串
  2. 修改引用库的 HTML 文件以指向版本化文件

(对于发布脚本来说,这通常是一件非常简单的事情)

现在您可以将 CSS/JS 的 Expires 设置为未来几年。每当您更改内容时,如果引用 HTML 指向新的 URI,浏览器将不再使用旧的缓存副本。

这会导致您想要的缓存行为,而不需要用户的任何内容。

于 2008-08-09T14:37:46.130 回答
6

当我找到格罗姆的答案时,我也想知道如何做到这一点。感谢您的代码。

我很难理解代码应该如何使用。(我不使用版本控制系统。)总而言之,您在调用样式表时包含时间戳 (ts)。您不打算经常更改样式表:

<?php 
    include ('grom_file.php');
    // timestamp on the filename has to be updated manually
    include_css('_stylesheets/style.css?ts=20080912162813', 'all');
?>
于 2008-09-13T16:54:51.573 回答