我有可在PHP 5.1.0+中制作的可缓存动态内容。我已经将正确的标题(包括Last-Modified和ETag)发送给客户。
我现在希望我的脚本能够在出现时回复$_SERVER['HTTP_IF_MODIFIED_SINCE']
和$_SERVER['HTTP_IF_NONE_MATCH']
。当条件匹配时,我想向客户回答HTTP 304 "Not Modified"
。
正确的条件是什么?我究竟发出304而不是整个内容?
有问题的答案 How to know when to send a 304 Not Modified response似乎正确地发出了这个问题,但我很难将该代码移植到PHP 5。
谢谢!
答案 0 :(得分:31)
我一直用:
function caching_headers ($file, $timestamp) {
$gmt_mtime = gmdate('r', $timestamp);
header('ETag: "'.md5($timestamp.$file).'"');
header('Last-Modified: '.$gmt_mtime);
header('Cache-Control: public');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
header('HTTP/1.1 304 Not Modified');
exit();
}
}
}
不记得我是写它还是从其他地方拿到它......
我通常以这种方式在文件的顶部使用它:
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
答案 1 :(得分:3)
您所引用的答案似乎包含了您所需要的一切。总结一下:
答案 2 :(得分:1)
这是我的render_file()函数的片段。
$last_modified = filemtime($filename);
if ($last_modified === false) {
throw new Exception('Modify date unknown');
}
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
$if_modified_since = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
if ($if_modified_since >= $last_modified) { // Is the Cached version the most recent?
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
exit();
}
}
header('Last-Modified: '.date('r', $last_modified)); // tz should be GMT according to specs but also works with other tzs
// other headers and contents go here
答案 3 :(得分:1)
如果我可以对Rich Bradshaw https://stackoverflow.com/users/16511/rich-bradshaw
最初的出色回答进行一些改进调整了此代码,现在100%通过了If-Modified-Since和If-None-Match检查。它还可以正确格式化“最后修改日期”,因为原始答案最后会发送+0000而不是GMT,并将VARY标头添加到304响应中。您可以在redbot.org上进行测试
<?php
function caching_headers ($file, $timestamp) {
$lastModified=filemtime($_SERVER['SCRIPT_FILENAME']);
$gmt_mtime = gmdate("D, d M Y H:i:s T", $lastModified);
header('ETag: "'.md5($timestamp.$file).'"');
header('Last-Modified: '.$gmt_mtime);
header('Cache-Control: must-revalidate, proxy-revalidate, max-age=3600');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
header('HTTP/1.1 304 Not Modified');
header("Vary: Accept-Encoding,User-Agent");
exit();
}
}
}
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
?>
答案 4 :(得分:0)
如果客户已经执行了 条件GET请求和访问是 允许,但文件还没有 修改后,服务器应该响应 使用此状态代码。 304 响应不得包含 消息体,因而永远 由第一个空行终止 在标题字段之后。
从 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
所以,如果发送304不发送正文。
答案 5 :(得分:0)
This article将回答有关缓存的所有问题
我发现添加了
RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]
在我的htaccess文件的底部(在所有rewriterule下面)工作。
答案 6 :(得分:-3)
为什么呢?
在对这个主题做了大量研究之后,我发现条件请求实际上会减慢网站的速度。在某些情况下情况并非如此,但总体而言映射到一般使用模式会导致吞吐量降低和缓存效率降低。
下进行。