动态CSS(通过PHP生成)的缓存头部信息

8

我的CSS文件实际上是一个PHP文件,使用content-type text/css进行服务,以便我可以在该文件中使用PHP变量。 style.php长这样:

<?php
header('Content-Type: text/css');
$bgColor = '#000';
?>

body { background:<?php print $bgColor; ?>; }

它按预期工作,但我有点担心浏览器是否会缓存动态创建的CSS文件。

当在Firebug中查看请求时,我发现每次重新加载页面时,浏览器似乎都会重新加载style.php

我已经尝试添加这些缓存头:

header('Cache-control: must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60 * 60 * 24) . ' GMT');

但是没有运气。每次加载页面时文件仍然会被加载。有哪些适当的头信息可以强制浏览器缓存文件一段时间?

2个回答

2
如果您希望文件被浏览器缓存,应将Cache-control头设置为public:
header('Cache-control: public');

must-revalidate表示浏览器会检查文件是否已更新,这将调用您的PHP脚本。


5
根据HTTP/1.1规范,"must-validate"并不意味着立即验证缓存内容——只有在缓存内容变得陈旧后(根据Expires头或Cache-Control中的max-age值指示),才会开始验证。但是一些浏览器似乎忽略了这个规范并发送了请求。然而,除非连接已经过身份验证,“public”并不适用。我建议使用“Cache-Control: max-age=86400”来加强Expires头中的时间。 - Brock Batsell
@Brock Batsell:感谢您的评论!这澄清了问题,现在使用max-age=XXXX可以正常工作。 - Max
如果文件内容被更改,请求的文件将不会被更新。OP要求如果内容被更改,则不应缓存该文件。如果文件内容没有更改,则应进行缓存。您提供的代码打开了“缓存”功能。它并不能解决OP的问题。 - Wissam El-Kik
以上答案必须更新以反映评论和解决方案。 - Basil Musa

2

这段代码可以解决你的问题。

它会检查“最后修改”的变量并为文件分配一个eTag。如果eTag被修改(或文件被修改),则会显示该文件。否则,会返回一个304 HTTP错误,说明页面未被修改。

eTag就是你要寻找的东西。

代码:

<?php 
// Custom variables
$variables = array('#CCC','#800'); // from db

// CSS Content
header('Content-type: text/css');

// Last Modified
$lastModified = filemtime(__FILE__);

// Get a unique hash of this file (etag)
$etagFile = md5_file(__FILE__);

// Get the HTTP_IF_MODIFIED_SINCE header if set
$ifModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);

// Get the HTTP_IF_NONE_MATCH header if set (etag: unique file hash)
$etagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);

// Set last-modified header
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $lastModified)." GMT");

// Set etag-header
header("Etag: $etagFile");

// Make sure caching is turned on
header('Cache-Control: public');

// Check if page has changed. If not, send 304 and exit
if(@strtotime($ifModifiedSince) == $lastModified || $etagHeader == $etagFile){
   header("HTTP/1.1 304 Not Modified");
   exit;
}
?>
body {background: <?php echo $variables[0]; ?>;}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接