【发布时间】:2015-09-04 17:43:50
【问题描述】:
我的想法很简单,获取所有 css 文件并在某个 css 文件更改时生成一个缩小的文件。然后告诉浏览器清除缓存。如果浏览器缓存中有未更改的文件,则使用它 - 因此用户无需每次都重新下载。
我正在使用以下代码片段来执行此操作。但是使用缓存的部分有点问题,大部分时间它都可以工作,但有时它告诉浏览器使用缓存版本(因为没有变化)并且浏览器正在使用旧版本并且用户必须进行客户端缓存刷新。
您能否给我一些建议如何做到这一点,以便每次发生更改时都会刷新客户端浏览器缓存,如果没有更改就使用缓存?
$cssFiles = getCssFiles();
$fm = new FileMinifier(FileMinifier::TYPE_CSS);
$lastModified = $fm->lastModification($cssFiles);
$savedLastModified = DateUtils::convertToTimestamp($this->system->systemSettings['cssLastChange']);
$etagFile = md5('css-file');
header("Content-type: text/css");
header("Pragma: public");
header('Cache-Control: public');
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModified) . " GMT");
header("Etag: $etagFile");
// if there is a change - generate new minified css
if ($lastModified > $savedLastModified)
{
// take files minify them, save it and redirect to output, update last change time
...
}
// or use already generated
else
{
$ifModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : 0);
$etagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);
// if it is in chache use it! - no need for redownloading
if (strtotime($ifModifiedSince) == $lastModified || $etagHeader == $etagFile)
{
header("HTTP/1.1 304 Not Modified");
exit;
}
$this->data['text'] = file_get_contents(SystemInfo::getServerRoot() . '/public/css/minified.css');
}
【问题讨论】:
-
99% 的时间浏览器自己都可以很好地工作,你想在这里解决什么问题?
-
我有另一个经验,如果我想更新一些 css 文件,很多人没有看到 chagnes。所以我开始做类似 ...css?v=2 之类的事情,这会强制浏览器重新缓存它,但我想自动化这个过程,所以我尝试了上面的解决方案。
-
你也许可以使用标题。需要重新验证或无缓存。
-
问题是我认为在 HTTP_IF_MODIFIED_SINCE 标头中可能提供了错误的信息,因为它表示没有更改,因此标头未修改被发送,因此浏览器将使用缓存。我需要一些条件,因为浏览器每次都会以其他方式重新下载它。我在缓存方面没有太多经验,我尝试了很多解决方案,我认为这个是最好的。但也许我做错了,所以我希望有人能给我一些建议或学习链接。
标签: php css caching browser-cache