Как кэшировать динамически создаваемые изображения?
У меня есть скрипт php, который генерирует *.png картинки, но не хранит их на сервере. Эти изображения будут показаны одному и тому же пользователю несколько раз. Я ищу способ кэшировать эти картинки. Я могу отправить заголовок статуса 304, браузер также объявляет веб-страницу как кэшированную при первом обновлении (как это видно в веб-инспекторе), но веб-страница отображается пустой. После второго обновления даже веб-инспектор показывает пустым.
Может ли кто-нибудь помочь мне и сказать, где я запутался?
Заметки:
- Я прочитал этот пост, но он мне не помог.
- Использование MAMP (версия PHP 7.0.10)
- Я новичок, извиняюсь за ужасный код.
Вот основные строки файла:
session_start();
header("Content-type: image/jpeg");
//A little require_once() here on some functions stored in an other file.
$originalSource = getSource($_GET['src']);
if (isset($_COOKIE[sha1($originalSource)]) && $_COOKIE[sha1($originalSource)]) {
header("HTTP/1.1 304 Not Modified");
die;
} else {
setcookie (sha1($originalSource), true, time()+10);
$offset = 10;
$expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
header($expire);
header("Cache-Control: max-age=".$offset);
header("Last-Modified: Wed, 25 Feb 2015 12:00:00 GMT");
}
//The entire image generation process after this
Спасибо за вашу помощь
1 ответ
Здесь ваш сервер решает, думает ли он, что браузер должен сохранять изображение в кэше или нет. Очевидно, это вряд ли авторитет в этом. Существует несколько причин, по которым браузер не может кэшировать изображение, например, если вы открываете инструменты инспектора (которые обычно отключают кэширование).
В браузере есть механизм информирования сервера о состоянии его кэша: заголовки HTTP If-None-Match
для ETags и If-Modified-Since
для истечения срока действия. Если в запросе присутствует любой из этих двух заголовков, это означает, что браузер все еще имеет копию кэшированного ресурса и с радостью примет 304
ответ вместо загрузки ресурса снова.
Если вы установите ETag
заголовок в вашем ответе, браузер сделает еще один запрос, используя If-None-Match
(это существенно заменяет ваш механизм cookie, более надежно); если вы просто установите срок действия, браузер снова проверит сервер, используя If-Modified-Since
заголовок. Это то, что вы должны основать свой 304
ответить на.
Пример использования ETags:
$hash = sha1($originalSource);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
if (
isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
trim($_SERVER['HTTP_IF_NONE_MATCH'], '"') === $hash
) {
header("HTTP/1.1 304 Not Modified");
exit;
}
header("Content-type: image/jpeg");
header("Cache-Control: max-age=$offset");
header("ETag: \"$hash\"");
// output image