Отключить кеш для некоторых изображений
Я генерирую некоторые изображения, используя PHP lib.
Иногда браузер не загружает новый сгенерированный файл.
Как я могу отключить кеш только для изображений, созданных мной динамически?
Примечание: я должен использовать одно и то же имя для созданных изображений с течением времени.
13 ответов
Распространенное и простое решение этой проблемы, которое выглядит как хак, но довольно переносимое, заключается в добавлении произвольно сгенерированной строки запроса в каждый запрос динамического изображения.
Так, например -
<img src="image.png" />
Станет
<img src="image.png?dummy=8484744" />
Или же
<img src="image.png?dummy=371662" />
С точки зрения веб-сервера доступ к одному и тому же файлу возможен, но с точки зрения браузера, кеширование невозможно.
Генерация случайных чисел может происходить либо на сервере при обслуживании страницы (просто убедитесь, что сама страница не кэшируется...), либо на клиенте (с использованием JavaScript).
Вам нужно будет проверить, справится ли ваш веб-сервер с этим трюком.
Стратегии кэширования браузера могут контролироваться HTTP-заголовками. Помните, что это всего лишь подсказка. Поскольку браузеры в этой (и любой другой) области ужасно несовместимы, вам потребуется несколько заголовков, чтобы получить желаемый эффект для ряда браузеров.
header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
Решение 1 не велико. Это работает, но добавление в конец ваших файлов изображений случайных или случайных строк запроса не является масштабируемым и заставит браузер повторно загружать и кэшировать каждую версию каждого отправляемого вами изображения.
Решение 2 бесполезно. Добавление nocache
Заголовки к файлу изображения не только очень сложно реализовать, но и совершенно нецелесообразно, потому что это требует от вас предсказать, когда оно понадобится заранее, при первой загрузке любого изображения, которое, по вашему мнению, может измениться в какой-то момент в будущем.
Введите Etags...
Абсолютно лучший способ решить эту проблему - использовать ETAGS внутри файла .htaccess в каталоге изображений. Ниже указано, что Apache отправляет уникальный хэш в браузер в заголовках файлов изображений. Этот хэш изменяется только при изменении файла изображения, и это изменение вызывает браузер для перезагрузки изображения при следующем запросе.
<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
Если вам нужно сделать это динамически в браузере с использованием javascript, вот пример...
<img id=graph alt=""
src="http://www.kitco.com/images/live/gold.gif"
/>
<script language="javascript" type="text/javascript">
var d = new Date();
document.getElementById("graph").src =
"http://www.kitco.com/images/live/gold.gif?ver=" +
d.getTime();
</script>
Я проверил все ответы, и лучший из них, кажется, (что не так):
<img src="image.png?cache=none">
вначале.
Однако, если вы добавите параметр cache=none (что является статическим словом "none"), это ничего не изменит, браузер все равно будет загружаться из кэша.
Решение этой проблемы было:
<img src="image.png?nocache=<?php echo time(); ?>">
где вы в основном добавляете метку времени Unix, чтобы сделать параметр динамическим, а не кеш, это сработало.
Однако моя проблема была немного иной: я загружал на лету сгенерированное изображение php-диаграммы и управлял страницей с помощью параметров $_GET. Я хотел, чтобы изображение считывалось из кеша, когда параметр GET URL-адреса остается прежним, и не кэшировалось при изменении параметров GET.
Чтобы решить эту проблему, мне нужно было хэшировать $_GET, но так как это массив, вот решение:
$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";
Редактировать:
Хотя вышеупомянутое решение работает просто отлично, иногда вы хотите использовать кэшированную версию, пока файл не будет изменен. (с помощью приведенного выше решения он полностью отключает кэш для этого изображения). Таким образом, для обслуживания кэшированного изображения из браузера, пока не будет изменено использование файла изображения:
echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
filemtime () возвращает время изменения файла.
Я знаю, что эта тема старая, но в Google это очень хорошо. Я обнаружил, что размещение этого в вашем заголовке работает хорошо;
<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">
Я просто искал решение для этого, и ответы выше не работали в моем случае (и у меня недостаточно репутации, чтобы комментировать их). Оказывается, что, по крайней мере, для моего варианта использования и браузера, который я использовал (Chrome на OSX), единственное, что, казалось, мешало кешированию, было:
Cache-Control = 'no-store'
Для полноты я сейчас использую все 3 "без кеша, без хранилища, обязательно повторная проверка"
Поэтому в моем случае (передача динамически сгенерированных изображений из Flask в Python) мне пришлось сделать следующее, чтобы, надеюсь, работать в максимально возможном количестве браузеров...
def make_uncached_response(inFile):
response = make_response(inFile)
response.headers['Pragma-Directive'] = 'no-cache'
response.headers['Cache-Directive'] = 'no-cache'
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response
Изменение источника изображения является решением. Вы действительно можете сделать это, добавив временную метку или случайное число к изображению.
Лучше было бы добавить контрольную сумму, например, данных, которые представляет изображение. Это позволяет кэшировать, когда это возможно.
Давайте добавим еще одно решение в группу.
Добавление уникальной строки в конце является идеальным решением.
example.jpg?646413154
Следующее решение расширяет этот метод и предоставляет возможность кэширования и получения новой версии при обновлении образа.
Когда изображение будет обновлено, время файла будет изменено.
<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>
Теперь выведите изображение:
<img src="images/example.jpg?<?php echo $filemtime; ?>" >
У меня была эта проблема и преодоление, как это.
var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
Я использовал это, чтобы решить мою подобную проблему... отображение счетчика изображений (от внешнего поставщика). Это не всегда обновлялось правильно. А после добавления случайного параметра все работает нормально:)
Я добавил строку с датой, чтобы обеспечить обновление по крайней мере каждую минуту.
пример кода (PHP):
$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";
Это приводит к src
ссылка как:
http://xy.somecounter.com/?id=1234567890&1207241014
Если у вас есть жестко закодированный URL-адрес изображения, например: http://example.com/image.jpg вы можете использовать php для добавления заголовков к вашему изображению.
Сначала вам нужно будет заставить apache обрабатывать ваш jpg как php. Смотрите здесь: Возможно ли выполнить PHP с расширением file.php.jpg?
Загрузите изображение (imagecreatefromjpeg) из файла, затем добавьте заголовки из предыдущих ответов. Используйте заголовок функции php для добавления заголовков.
Затем выведите изображение с помощью функции imagejpeg.
Обратите внимание, что php обрабатывать изображения в формате jpg крайне небезопасно. Также имейте в виду, что я не тестировал это решение, так что вам решать, как оно работает.
Просто, отправьте один заголовок местоположения.
Мой сайт содержит одно изображение, и после загрузки изображение там не меняется, затем я добавляю этот код:
<?php header("Location: pagelocalimage.php"); ?>
Работает для меня.