У меня есть файл PHP, который возвратит то же самое с тем же $ _GET параметры каждый раз, когда - это детерминировано.
К сожалению для эффективности (этот файл требуют очень часто), значения по умолчанию Apache к "200 хорошо" ответам каждый раз, когда страницу PHP требуют, заставляя пользователя загрузить файл снова.
Есть ли любой способ отправить a 304 Not Modified
заголовок, если и только если параметры являются тем же?
Премия: я могу установить время истечения на нем, так, чтобы, если кэшируемая страница является больше, чем, скажем, три дня, она отправила "200 хорошо" ответов?
Без кэширования страницы самостоятельно (или хотя бы ее Etag) вы не сможете использовать 304. Полноценный алгоритм кэширования несколько выходит за рамки, но общая идея:
<?php
function getUrlEtag($url){
//some logic to get an etag, possibly stored in memcached / database / file etc.
}
function setUrlEtag($url,$etag){
//some logic to get an etag, possibly stored in memcached / database / file etc.
}
function getPageCache($url,$etag=''){
//[optional]some logic to get the page from cache instead, possibly not even using etag
}
function setPageCache($url,$content,$etag=''){
//[optional]some logic to save the page to cache, possibly not even using etag
}
ob_start();
$etag = getUrlEtag($_SERVER['REQUEST_URI']);
if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
header("HTTP/1.1 304 Not Modified");
exit;
}
if(($content=getPageCache($_SERVER['REQUEST_URI'],$etag))!==false){
echo $content;
exit;
}
?>
//the actual page
<?php
$content = ob_get_clean();
setUrlEtag($_SERVER['REQUEST_URI'],$etag=md5($url.$content));
function setPageCache($_SERVER['REQUEST_URI'],$content,$etag);
header("Etag: $etag");
echo $content;
?>
Применяются все распространенные ошибки: вы, возможно, не можете отображать страницы кеша для зарегистрированных пользователей, кеширование частичного контента может быть более желательным, вы сами несете ответственность за предотвращение устаревшего контента в кеше (возможно, используя триггеры в бэкэнде или базе данных при изменениях, или просто поиграйте с логикой getUrlEtag
) и т. д.
Вы также можете поиграть с HTTP_IF_MODIFIED_SINCE
, если это легче контролировать.
Пробовали ли вы заголовок («HTTP / 1.0 304 не изменен»);
в вызываемом коде PHP? Если вы незнакомы, вы захотите вставить это в свой код ДО того, как начнете выводить что-либо в буфер.
Как правило, вы возвращаете коды состояния HTTP с помощью функции заголовка:
Header("HTTP/1.1 304 Not Modified");
exit();
Однако , одного этого недостаточно.
Проблема в том, что вы не знаете, как запрашивали файл, поэтому вам потребуется немного сотрудничества с браузером.
Вы можете найти заголовки If-modified-Since
во входящем запросе и вернуть соответствующий код состояния, если он присутствует и находится в пределах диапазона дат.
Если вы отправите правильный заголовок Expires
при первоначальном создании PHP, тогда кеш браузера или прокси-сервера может решить не получать запрос вообще (хотя более вероятно, что они установят ] If-modified-Since
заголовок).Без заголовка Expires
браузер, скорее всего, всегда будет повторно выполнять полный запрос.
Для получения дополнительной информации см. http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html и выполните поиск «14.25»
Браузер отобразит GET
параметры для кэшированной копии, кстати. Там работать не нужно.