【问题标题】:Minify CSS on the fly: leveraging browser caching动态缩小 CSS:利用浏览器缓存
【发布时间】:2012-12-07 19:52:50
【问题描述】:

我正在编写一个脚本,它将合并和缩小请求的 CSS 文件,然后将它们回显。我已经完成了大部分工作,但我还停留在一个小而非常重要的部分:利用浏览器缓存。

我们网站的大多数访问者都是新来的,而且很少回来。所以我们真正担心的是同一会话中页面请求之间的缓存。比如,他们点击了我们的主页,然后导航到其他几个页面并离开。

我遇到的问题是我在会话中存储了每个特定文件集的最后请求时间的时间戳。因此,如果我想要 main.css 和 internet.css 这个请求,然后是 main.css 和 phone.css 下一页视图,那么最后一个请求的时间戳将被更新,但如果我再次请求同一组文件,时间戳将与上次保持不变。

希望我说得有道理。问题是,当一个文件从上次请求到这个请求没有改变时,我返回 304 not modified。但是,浏览器并没有像应有的那样缓存 css。有什么想法为什么不呢?

你可以在这里看看我的代码:https://gist.github.com/4235836(我通常会把它放在这里,但它有点长)

【问题讨论】:

    标签: php css caching browser-cache


    【解决方案1】:

    我认为您应该在发送 304 之前检查请求标头 If-modified-since:

    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && 
        strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $minifier->lastModified)
    {
        header('HTTP/1.0 304 Not Modified');
        exit;
    }
    

    还要注意出口。如果您发送 304,则意味着客户端已经拥有最新版本,因此您应该在那里退出脚本。

    编辑:

    当使用过期标头时,浏览器会假定它已经拥有最新版本。所以它甚至不会向服务器发出请求,这与使用 HTTP_IF_MODIFIED_SINCE 标头不同。

    所以你可能还想添加:

    header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60 * 24)));
    

    然后,为了确保文件更改后它会请求新版本,您可以执行以下操作:

    <link rel="stylesheet" type="text/css" 
        href="minify.php?v=<?php echo filemtime($theFileToMinify) ?>">
    

    【讨论】:

    • 我遇到的一个问题是实时服务器没有安装 mod_headers 和 mod_expires。我也无权安装它们,因此未设置 HTTP_IF_MODIFIED_SINCE。我想出了我的解决方案来解决这个问题,但无论哪种方式,当我发送 304 时,浏览器仍然不会从它的缓存中加载 css。
    • 如果您通过 PHP 设置标头,我认为您不需要 mod_headers 和 mod_expires
    • 当我转储 $_SERVER HTTP_IF_MODIFIED_SINCE 时不存在。我知道这是因为那些模块没有安装/启用,但是我可能是错的。我可以直接设置它们,但我所做的基本上就是这样,无需修改 $_SERVER 数组。
    • 如果浏览器在上次请求该文件时收到 Last-Modified 标头,它将发送 HTTP_IF_MODIFIED_SINCE。手动刷新页面也可能会阻止浏览器发送 HTTP_IF_MODIFIED_SINCE。
    • 啊,好的,我已经实施了您的解决方案,它似乎正在工作,所以我会给您检查。感谢您的帮助!
    猜你喜欢
    • 2016-06-04
    • 2014-02-07
    • 2011-10-15
    • 2014-07-29
    • 2018-05-28
    • 2012-10-13
    相关资源
    最近更新 更多