经过大量搜索、阅读我找到的每个教程并在这里提出一些问题后,我终于设法正确地(至少我认为)回答了 if-none-match 和 if-modified-since HTTP 请求.
After searching a lot, reading every tutorials I've found and asking some questions here, I've finally managed to answer corrctly (at least I think) to if-none-match and if-modified-since HTTP requests.
快速回顾一下,这就是我在每个可缓存页面上所做的:
To do a quick recap, this is what I do on every pages cacheable:
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"将在英文网址/en/home"和法文网址/fr/accueil"下提供.
Also, every page have it's own URL (for every languages). For example, "index.php" will be served under URL "/en/home" in English and "/fr/accueil" in French.
我的大问题是仅在需要时对 if-none-match 和 if-modified-since HTTP 请求响应304 Not Modified".
My big problem was to answer a "304 Not Modified" to if-none-match and if-modified-since HTTP requests only when needed.
我找到的最好的文档是:http://rithiur.anthd.com/tutorials/conditionalget.php
The best doc I've found is: http://rithiur.anthd.com/tutorials/conditionalget.php
这是我做的实现(这段代码在可以缓存的页面上称为ASAP):
And this is the implementation I did of it (this piece of code is called ASAP on pages that can be cached):
$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();
}
}
我的问题有两个:
顺便说一句,我只使用 PHP 5.1.0+(我不支持低于它的版本).
BTW, I use PHP 5.1.0+ only (I don't support versions lower that that).
增加了赏金……我期待高质量的回答.如果您在猜测某事,请不要回答/投票!
Added bounty... I expect quality answer. Don't answer/vote if you are guessing something!
以下是可能有用的函数:
Here is the function that might help:
function isModified($mtime, $etag) {
return !( (
isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
&&
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mtime
) || (
isset($_SERVER['HTTP_IF_NONE_MATCH'])
&&
$_SERVER['HTTP_IF_NONE_MATCH'] == $etag
) ) ;
}
我建议你看看下面的文章:http://www.peej.co.uk/articles/http-caching.html
I suggest that you take a look at the following article: http://www.peej.co.uk/articles/http-caching.html
更新:
[AlexV] 甚至可以同时接收 if-none-match 和 if-modified-since 吗?
[AlexV] Is is even possible to receive if-none-match AND if-modified-since at the same time?
你绝对可以同时设置.然而:
You can definitely have both set. However:
如果没有实体标签匹配,那么服务器可以执行请求的方法,就好像 If-None-Match 头字段不存在一样,但也必须忽略任何 If-Modified-Since 头字段中的要求.也就是说,如果没有实体标签匹配,则服务器不得返回 304(未修改)响应.
If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request. That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response.
RFC2616 #14.26
示例值(W 代表弱";阅读更多内容RFC2616 #13.3.3):
Example values (W stands for 'weak'; read more in RFC2616 #13.3.3):
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
If-None-Match: *
作为一种特殊情况,值*"匹配资源的任何当前实体.
As a special case, the value "*" matches any current entity of the resource.
这篇关于我在 PHP 中实现的 HTTP 条件获取答案是否可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
在 SELECT(MYSQL/PHP) 中加入 2 个表Joining 2 tables in SELECT(MYSQL/PHP)(在 SELECT(MYSQL/PHP) 中加入 2 个表)
如何使<option selected=“selected">由How to make lt;option selected=quot;selectedquot;gt; set by MySQL and PHP?(如何使lt;option selected=“selectedgt;由 MySQL 和 PHP 设置?)
使用 PHP 中的数组自动填充选择框Auto populate a select box using an array in PHP(使用 PHP 中的数组自动填充选择框)
PHP SQL SELECT where like search item with multiple wordsPHP SQL SELECT where like search item with multiple words(PHP SQL SELECT where like search item with multiple words)
json_encode 从 MSSQL-SELECT 产生 JSON_ERROR_UTF8json_encode produce JSON_ERROR_UTF8 from MSSQL-SELECT(json_encode 从 MSSQL-SELECT 产生 JSON_ERROR_UTF8)
MySQL ORDER BY rand(),名称 ASCMySQL ORDER BY rand(), name ASC(MySQL ORDER BY rand(),名称 ASC)