【发布时间】:2010-01-07 16:32:50
【问题描述】:
经过大量搜索,阅读了我找到的每个教程并在这里提出了一些问题,我终于成功地(至少我认为)正确回答了 if-none-match 和 if-modified-since HTTP 请求。
简要回顾一下,这是我对每个可缓存页面所做的:
session_cache_limiter('public'); //Cache on clients and proxies
session_cache_expire(180); //3 hours
header('Content-Type: ' . $documentMimeType . '; charset=' . $charset);
header('ETag: "' . $eTag . '"'); //$eTag is a MD5 of $currentLanguage + $lastModified
if ($isXML)
header('Vary: Accept'); //$documentMimeType can be either application/xhtml+xml or text/html for XHTML (based on $_SERVER['HTTP_ACCEPT'])
header('Last-Modified: ' . $lastModified);
header('Content-Language: ' . $currentLanguage);
此外,每个页面都有自己的 URL(适用于每种语言)。例如,“index.php”将在英文的 URL“/en/home”和法语的“/fr/accueil”下提供。
我的大问题是仅在需要时回答“304 Not Modified”到 if-none-match 和 if-modified-since HTTP 请求。
我找到的最好的文档是: http://rithiur.anthd.com/tutorials/conditionalget.php
这是我对它的实现(这段代码在可以缓存的页面上被称为 ASAP):
$ifNoneMatch = array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
$ifModifiedSince = array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
if ($ifNoneMatch !== false && $ifModifiedSince !== false)
{
//Both if-none-match and if-modified-since were received.
//They must match the document values in order to send a HTTP 304 answer.
if ($ifNoneMatch == $eTag && $ifModifiedSince == $lastModified)
{
header('Not Modified', true, 304);
exit();
}
}
else
{
//Only one header received, it it match the document value, send a HTTP 304 answer.
if (($ifNoneMatch !== false && $ifNoneMatch == $eTag) || ($ifModifiedSince !== false && $ifModifiedSince == $lastModified))
{
header('Not Modified', true, 304);
exit();
}
}
我的问题有两个:
- 这是正确的方法吗?我的意思是当发送 if-none-match 和 if-modified-since 时,both 必须匹配才能回答 304,如果只发送两者之一,则仅匹配此一个即可发送304?
- 在此处描述的上下文中使用时,这 2 个 sn-ps 是否对公共缓存友好(我的意思是代理 和 Web 浏览器上的缓存友好)?
顺便说一句,我只使用 PHP 5.1.0+(我不支持低于该版本的版本)。
编辑:增加赏金...我希望得到高质量的答案。如果您猜到了什么,请不要回答/投票!
【问题讨论】:
标签: php http caching header http-headers