Сделайте возврат страницы PHP “304 Не Измененным”, если он не был изменен

У меня есть файл PHP, который возвратит то же самое с тем же $ _GET параметры каждый раз, когда - это детерминировано.

К сожалению для эффективности (этот файл требуют очень часто), значения по умолчанию Apache к "200 хорошо" ответам каждый раз, когда страницу PHP требуют, заставляя пользователя загрузить файл снова.

Есть ли любой способ отправить a 304 Not Modified заголовок, если и только если параметры являются тем же?

Премия: я могу установить время истечения на нем, так, чтобы, если кэшируемая страница является больше, чем, скажем, три дня, она отправила "200 хорошо" ответов?

5
задан Christian Mann 4 June 2010 в 23:58
поделиться

3 ответа

Без кэширования страницы самостоятельно (или хотя бы ее 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 , если это легче контролировать.

10
ответ дан 18 December 2019 в 08:26
поделиться

Пробовали ли вы заголовок («HTTP / 1.0 304 не изменен»); в вызываемом коде PHP? Если вы незнакомы, вы захотите вставить это в свой код ДО того, как начнете выводить что-либо в буфер.

http://php.net/manual/en/function.header.php

2
ответ дан 18 December 2019 в 08:26
поделиться

Как правило, вы возвращаете коды состояния 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 параметры для кэшированной копии, кстати. Там работать не нужно.

7
ответ дан 18 December 2019 в 08:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: