如何正确地为CSS服务



说我出于某种原因想通过PHP提供CSS(因为预处理、合并等)。我需要在我的PHP中做些什么才能让它正常工作?除了最明显的:

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

与缓存、修改时间、etag等相关的头呢?我应该使用哪些,为什么以及如何使用?我将如何解析传入的标头并做出适当的响应(例如304未修改)?


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

注意2:我真的很想知道如何正确地做到这一点。我觉得这个问题上的大部分活动都变成了我为自己为什么要这样做辩护,而不是得到如何做到这一点的答案。如果有人能回答我的问题,而不仅仅是提出SASS之类的建议,我将不胜感激。我确信它很棒,我可能会尝试一下,但这不是我现在所要求的。我想知道如何通过PHP为CSS服务,并学习如何正确处理缓存之类的事情

值得称赞的努力。缓存得到的善意太少了。请欣赏我的短文,我试图在你的路上帮助你。

摘要

发送ETagLast-Modified标头将使浏览器能够在后续请求时将If-Modified-SinceIf-None-Match标头发送回服务器。然后,在适用的情况下,您可以使用304 Not Modified HTTP状态代码和空正文(即Content-Length: 0)进行响应。包含Expires标头将帮助您在某一天内容确实发生更改时提供新内容。

学徒

听起来很简单,但要做到恰到好处可能有点棘手。幸运的是,我们所有人都有很好的指导。

一旦你启动并运行了它,请求助于REDbot来帮助你平滑你可能留下的任何粗糙的角落。

专家

对于ETag的值,您将希望有一些可以复制的内容,但无论何时内容都会更改。否则,您将无法判断传入值是否匹配。可再现值的一个很好的候选者是通过高速缓存提供的文件的mtime的MD5哈希,该值在内容发生变化时仍会发生变化。在您的情况下,它可能是所有正在合并的文件的总和。

对于Last-Modified,逻辑答案是所服务的文件的实际mtime。为什么忽略显而易见的东西。或者,对于一组文件,在您的情况下,使用该组文件中最新的mtime

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

您可能还想包含Cache-Control标头,让可能的代理知道如何正确地为其客户端提供服务。

学者

要想更具体地回答您的问题,请参阅您之前的这些问题:

  • 我想将哪些标头与304响应一起发送
  • 使浏览器同时发送"如果无匹配"one_answers"如果修改自"
  • HTTP,如果没有匹配,并且如果自PHP中的304澄清之后进行了修改
  • 我在PHP中实现HTTP Conditional Get answers可以吗

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

为了了解如何正确编写自己的资产服务器,我强烈建议您阅读Assetc的源代码。它具有很强的评论性和可读性,您将了解到许多关于缓存、缩小以及Assetic做得很好的其他方面的最佳实践。

一种常见的模式是包含一个无意义的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") . '"');

I刚刚在这里解释了为什么我认为PHP处理的CSS不是一个好主意;我相信大多数实现它的人会更好地使用另一个应用程序结构。看一看。

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

Content-Type的标题是一个好的开始,但不是棘手的部分。。。

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

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

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

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

最新更新