如何正确地提供CSS

时间:2012-02-03 13:56:22

标签: php css caching header

说我出于某种原因希望通过PHP提供我的CSS(因为预处理,合并等)。我需要在PHP中做些什么来使这项工作顺利进行?除了最明显的:

header('content-type: text/css; charset=utf-8');

与缓存,修改时间,etags等相关的标题怎么样?我应该使用哪些,为什么以及如何使用?我如何解析传入的标题并做出适当的响应(例如304 Not Modified)?


注意:我知道这可能很棘手,在我将它作为常规CSS文件部署之前,做我想做的事情要容易得多。如果我想这样做,我就不会问这个问题了。我很好奇如何正确地做到这一点,并想知道。我事先用CSS做或不能做的事情是无关紧要的;我只是想知道如何正确地服务它:)

注2:我真的很想知道如何正确地做到这一点。我觉得这个问题上的大部分活动都变成了我为什么要这样做而捍卫我,而不是得到如何做到这一点的答案。如果有人能够回答我的问题而不仅仅是建议像SASS这样的事情,我将非常感激。我确定它很棒,我可能会在某个时候尝试一下,但这不是我现在要问的问题。我想知道如何通过PHP提供CSS,并学习如何正确处理缓存和类似的东西。

5 个答案:

答案 0 :(得分:6)

值得称道的努力。缓存得到的好处太少了。请尽情享受我的短篇小说,试图帮助你。

摘要

发送ETagLast-Modified标头可让浏览器在后续请求中向您的服务器发送If-Modified-SinceIf-None-Match标头。然后,您可以在适用时使用304 Not Modified HTTP状态代码和空体(即Content-Length: 0)进行回复。包含Expires标题可以帮助您在内容确实发生变化时提供新内容。

学徒

听起来很简单,但要做得恰到好处可能有点棘手。幸运的是,我们都有really good guidance可用。

启动并运行后,请转到REDbot,以帮助您消除可能留下的任何粗糙角落。

专家

对于ETag的值,您需要具有可以重现的内容,但只要内容有效,它仍会发生变化。否则,您将无法判断传入值是否匹配。对于可重现的值而言,当内容发生时仍然会发生变化的良好候选者是通过缓存提供的文件的mtime的MD5哈希。在您的情况下,它可能是所有合并文件的总和。

对于Last-Modified,逻辑答案是所服务文件的实际mtime。为什么忽视明显的。或者对于一组文件(如您的情况),请使用最新的mtime

对于Expires,只需为资产选择合适的TTL或生存时间。将此数字添加到资源的mtime或您为Last-Modified选择的值,即可获得答案。

您可能还希望包含Cache-Control标题,以便让我们知道如何正确地为客户提供服务。

学者

要对您的问题作出更具体的回答,请在您之前参考这些问题:

答案 1 :(得分:3)

通过PHP提供CSS(或JavaScript)的最简单方法是使用Assetic,这是一个超级有用的PHP资产管理器,类似于Django的contrib.staticfiles或Ruby的Jammit。它处理缓存和缓存失效,动态缩小,压缩以及其他答案中提到的所有“棘手的位”。

要了解如何正确编写自己的资产服务器,我强烈建议您阅读Assetic的源代码。它非常评论和可读,您将学习很多关于缓存,缩小以及Assetic所做的其他一切的最佳实践。

答案 2 :(得分:2)

一种常见的模式是包含无意义的GET参数。实际上,堆栈交换站点确实很简单:

<link ... href="http://cdn.sstatic.net/stackoverflow/all.css?v=0285b0392b5c">

v(版本)可能是某种哈希,可能是css文件本身。它们不存储旧工作表,只是强制浏览器下载新文件而不使用缓存文件的方法。

使用此设置,可以将Cache-Control:max-age设置为较大的值。

如果文件未被修改,ETag将使服务器回复304,您也可以使用相同的哈希:

header('ETag: "' . md5("path to css file") . '"');

答案 3 :(得分:1)

只是完成了解释here为什么我认为PHP处理的CSS不是一个好主意;我相信大多数实现它的人会更好地服务于另一个应用程序结构。看一看。

如果必须这样做,那么进行缓存工作将需要独立跟踪每个变量并让客户端发送一个唯一标识该变体的参数(因此您可以说“未修改”)。

Content-Type标题是一个好的开始,但不是那个棘手的问题......

答案 4 :(得分:0)

你必须在javascript文件的末尾添加查询字符串,这是一个很好的选择,说它是新文件,直到浏览器认为相同的css文件

www.example.com/css/tooltip.css?version1.0  

www.example.com/css/tooltip.css?12-01-2012

所以浏览器会理解它再次重新加载的新文件,将其保存在缓存中直到下一个版本,并且如果你在查询字符串末尾使用php附加自动日期,则易于维护。