Кэширование на стороне клиента (HTTP/1.0 304 Not Modified)

SiMM

Новичок
Кэширование на стороне клиента (HTTP/1.0 304 Not Modified)

Хотелось бы воспользоваться данной функцией браузера, но не знаю, как. При тестовой "прослушке" узрел следующее:
При первом запросе к файлу сервер выдал клиенту следующие данные:
Код:
Last-Modified: Tue, 30 Mar 2004 13:57:13 GMT
ETag: "1c9113-1be2-40697cb9"
При последующих запросах клиент посылает серверу
Код:
If-Modified-Since: Tue, 30 Mar 2004 13:57:13 GMT
If-None-Match: "1c9113-1be2-40697cb9"
на что получает в отклике от сервера
Код:
HTTP/1.0 304 Not Modified
Date: Thu, 01 Apr 2004 09:47:56 GMT
ETag: "1c9113-1be2-40697cb9"
Как видим, в If-Modified-Since передаётся дата создания файла на сервере, полученная при первом запросе к файлу, при повторных запросах в Date клиент получает дату сервера для сравнения, остаётся вопрос - как формируется ETag и как получить в скрипте значения If-Modified-Since и If-None-Match, выданные клиентом?
На вопрос "а зачем так заморачиваться?" отвечу "что нада" ;) Дело в том, что файлы отдаются скриптом (зачем - обсуждению не подлежит), а исходящий с сервера траффик (да и входящий траффик клиента) хотелось бы беречь.
 

Falc

Новичок
SiMM
Etag - некий уникальный хеш документа.
Как наиболее распространеный вариант считай md5()
 

SiMM

Новичок
Falc, это несколько затруднительно - дело в том, что файл отдаётся не совсем таким, какой он есть - часть информации замещается на лету. Хотя это и не проблема, но в моём случае, думаю, будет достаточно использовать константу. А наличие и положение всяких включений в ETag (я о дефисах) не имеет никакого значения?
И ещё - если не затруднит, я так и не смог найти, как получить в PHP клиентские If-Modified-Since и If-None-Match (по заголовкам полно топиков - но все как правило их передают). Может подскажете?
 

Falc

Новичок
SiMM
>>файл отдаётся не совсем таким, какой он есть - часть информации замещается на лету. Хотя это и не проблема, но в моём случае, думаю, будет достаточно использовать константу.

Вот после замещения тебе и надо подсчитать md5.

>>А наличие и положение всяких включений в ETag (я о дефисах) не имеет никакого значения?
Имеет значение только его уникальность для каждого документа.

>>И ещё - если не затруднит, я так и не смог найти, как получить в PHP клиентские If-Modified-Since и If-None-Match
[m]getallheaders[/m]
 

SiMM

Новичок
Автор оригинала: Falc
SiMM
>>файл отдаётся не совсем таким, какой он есть - часть информации замещается на лету. Хотя это и не проблема, но в моём случае, думаю, будет достаточно использовать константу.

Вот после замещения тебе и надо подсчитать md5.
Это то понятно - просто процедуру замещения данных трогать не хотелось, делать ob_start с вытекающими - жалко памяти сервера (сгенерированный файл не очень то маленький, да и целесообразность затрат ресурсов сервера на обсчёт md5 там, где это не критично, сомнительна).
>>А наличие и положение всяких включений в ETag (я о дефисах) не имеет никакого значения?
Имеет значение только его уникальность для каждого документа.
Ясно.
>>И ещё - если не затруднит, я так и не смог найти, как получить в PHP клиентские If-Modified-Since и If-None-Match
[m]getallheaders[/m]
Большое спасибо.
 

Falc

Новичок
SiMM
>>делать ob_start с вытекающими

Зато это даст 100% увереность того что ты не пошлешь устаревший документ.
 

SiMM

Новичок
Falc, чтобы не было недоразумений - наверно лучше раскрыть карты ;) В моём случае документы можно считать статическими - это jpg-картинки, в которых я подмениваю EXIF-информацию - сами картинки при этом остаются прежними. Потери от того, что какому-либо пользователю придёт картинка с устаревшим EXIF'ом не столь заметна, если же это будет для меня критично - в любой момент я смогу изменить способ генерирования ETag так, чтобы он был "несовместим" со старым способом :) Если же картинка всё же изменится, это тоже не страшно - дата создания файла в этом случае так же изменится, что, думаю, заставит браузер задуматься ;)
 

Falc

Новичок
SiMM
Тогда тебе могу предложить такой алгоритм:
$ETag = md5( $EXIF . $jpeg_file_date );
 

SiMM

Новичок
Falc, спасибо огромное за помощь. Решил сделать кэширование и генерируемых страниц - однако ничего не получилось. В кратце делал следующим образом
PHP:
ob_start();
echo $_SERVER['REQUEST_URI']; // некая динамическая часть скрипта
$content=ob_get_contents();
ob_end_clean();
$headers=getallheaders();
$lastmodified=gmdate('D, d M Y H:i:s',filemtime(__FILE__)).' GMT'; // конечно, несовсем корректно, но пока так :-)
$ETag=md5($content);
if (@$headers['If-Modified-Since']==$lastmodified && @$headers['If-None-Match']==$ETag){
  header('HTTP/1.0 304 Not Modified');
  header("ETag: $ETag");
}
else{
  header('HTTP/1.0 200 OK');
  header("Last-Modified: $lastmodified");
  header("ETag: $ETag");
  print_r($headers);
  echo $content;
}
По первому обращению к страничке отклик выглядит так:
Код:
HTTP/1.1 200 OK
Last-Modified: Fri, 02 Apr 2004 08:21:23 GMT
ETag: a7524b4c5704ed521ef77edc12f4ed87
т.е. всё в порядке. При последующем запросе браузером происходит странность
Код:
Cache-Control: no-cache
а If-Modified-Since и If-None-Match клиентом, судя по print_r, не выдаются - соответственно получаю то, что получаю - в отклике опять выдаю всю страницу вместо желаемого 304. Не подскажете, что я делаю не так и как избавиться от no-cache? Может хидер какой надо отсылать?
 

Alien

Новичок
Если браузер шлет "Cache-Control: no-cache" то он не шлет "If-Modified-Since".
Проверяй почему - к серверной части это никакого отношения не имеет.
 

SiMM

Новичок
Alien, похоже вы отчасти правы. Оказалось, что в отсутсвии некоторых хидеров виноват Proxomitron, которым я и смотрел принимаемые и передаваемые пакеты (вот что значит микроскоп в руках неандертальца ;) ). В IE вроде всё заработало (дополнительно добавил Cache-Control: private Pragma: cache и Expires на довольно далёкий срок), однако Opera продолжает упорно слать no-cache. Может кто-нибудь сталкивался с подобной задачкой и уже натыкался на грабли - поделится опытом?
Ещё возник вопрос - насколько я понял, стоит замутить сессии, и о кэшировании можно будет забыть - а как обстоят дела с куками?
 
Сверху