Отключить кеш для некоторых изображений - PullRequest
93 голосов
/ 08 апреля 2009

Я генерирую некоторые изображения, используя PHP lib.

Иногда браузер не загружает новый сгенерированный файл.

Как отключить кэш только для изображений, созданных мной динамически?

Примечание: я должен использовать одно и то же имя для созданных изображений с течением времени.

Ответы [ 13 ]

198 голосов
/ 08 апреля 2009

Распространенное и простое решение этой проблемы, которое выглядит как хак, но довольно переносимое, заключается в добавлении произвольно сгенерированной строки запроса в каждый запрос динамического изображения.

Так, например -

<img src="image.png" />

станет

<img src="image.png?dummy=8484744" />

Или

<img src="image.png?dummy=371662" />

С точки зрения веб-сервера доступ к тому же файлу возможен, но с точки зрения браузера кэширование не может быть выполнено.

Генерация случайных чисел может происходить либо на сервере при обслуживании страницы (просто убедитесь, что сама страница не кэшируется ...), либо на клиенте (с использованием JavaScript).

Вам необходимо проверить, может ли ваш веб-сервер справиться с этим трюком.

39 голосов
/ 08 апреля 2009

Стратегиями кэширования браузера можно управлять с помощью заголовков HTTP. Помните, что это всего лишь подсказка. Поскольку браузеры в этой (и любой другой) области крайне несовместимы, вам потребуется несколько заголовков, чтобы получить желаемый эффект для ряда браузеров.

header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
11 голосов
/ 01 июня 2016

Решение 1 не велико. Это работает, но добавление в конец ваших файлов изображений необработанных случайных или временных меток строк запроса не масштабируется и заставит браузер повторно загружать и кэшировать каждую версию каждого. изображение, которое вы отправляете.

Решение 2. бесполезно. Добавление nocache заголовков к файлу изображения не только очень сложно реализовать, но и совершенно неосуществимо, поскольку требует от вас предсказать, когда оно потребуется forward , при первой загрузке любого изображения, которое, по вашему мнению, может измениться в какой-то момент в будущем.

Введите Etags ...

Абсолютно лучший способ Я нашел, чтобы решить эту проблему - использовать ETAGS внутри файла .htaccess в каталоге изображений. Далее Apache сообщает об отправке уникального хэша в браузер в заголовках файла изображения. Этот хэш изменяется только при изменении файла изображения, и это изменение вызывает браузер для перезагрузки изображения при следующем запросе.

<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
10 голосов
/ 25 мая 2011

Если вам нужно сделать это динамически в браузере с использованием 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>
9 голосов
/ 19 ноября 2015

Я проверил все ответы, и лучший из них, кажется, (а это не так):

<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'>";

Редактировать

Хотя вышеприведенное решение работает просто отлично, иногда вы хотите использовать кэшированную версию, пока файл не будет изменен. (с вышеупомянутым решением это полностью отключает кеш для этого изображения) Итак, для обслуживания кэшированного изображения из браузера UNTIL изменилось использование файла изображения:

echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";

filemtime () возвращает время изменения файла.

3 голосов
/ 05 сентября 2013

Изменение источника изображения является решением. Вы действительно можете сделать это, добавив временную метку или случайное число к изображению.

Лучше было бы добавить контрольную сумму, например, данных, которые представляет изображение. Это позволяет кэшировать, когда это возможно.

3 голосов
/ 25 декабря 2012

Я знаю, что эта тема старая, но в 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">
2 голосов
/ 13 июля 2016

Я просто искал решение для этого, и ответы выше не сработали в моем случае (и у меня недостаточно репутации, чтобы комментировать их). Оказывается, что, по крайней мере для моего сценария использования и браузера, который я использовал (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
1 голос
/ 04 ноября 2017

У меня была эта проблема и преодоление, как это.

var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
0 голосов
/ 20 января 2016

Давайте добавим еще одно решение в группу.

Добавление уникальной строки в конце является идеальным решением.

example.jpg?646413154

Следующее решение расширяет этот метод и обеспечивает как возможность кэширования, так и выбор новой версии при обновлении образа.

Когда изображение обновляется, filemtime будет изменено.

<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>

Теперь выведите изображение:

<img src="images/example.jpg?<?php echo $filemtime; ?>" >
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...