Я получаю доступ к ссылке на своем сайте, которая будет предоставлять новое изображение при каждом обращении к нему.
Проблема, с которой я сталкиваюсь, заключается в том, что если я попытаюсь загрузить изображение в фоновом режиме, а затем обновить его на странице, изображение не изменится - хотя оно обновляется при перезагрузке страницы.
var newImage = new Image();
newImage.src = "http://localhost/image.jpg";
function updateImage()
{
if(newImage.complete) {
document.getElementById("theText").src = newImage.src;
newImage = new Image();
number++;
newImage.src = "http://localhost/image/id/image.jpg?time=" + new Date();
}
setTimeout(updateImage, 1000);
}
Заголовки, как их видит FireFox:
HTTP/1.x 200 OK
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Server: Microsoft-HTTPAPI/1.0
Date: Thu, 02 Jul 2009 23:06:04 GMT
Мне нужно принудительно обновить только это изображение на странице. Любые идеи?
javascript
image
url
refresh
QueueHammer
источник
источник
Ответы:
Попробуйте добавить кеш-взломщик в конце URL:
Это автоматически добавит текущую метку времени при создании изображения и заставит браузер снова искать изображение, а не извлекать его в кэш.
источник
'image.jpg?' + (+new Date())
Date.now()
для этогоMath.random()
Я видел много вариантов ответов о том, как это сделать, поэтому я решил обобщить их здесь (плюс добавить 4-й метод моего собственного изобретения):
(1) Добавьте уникальный параметр запроса к кешу в URL, например:
Плюсы: 100% надежность, быстрая и простая для понимания и реализации.
Минусы: полностью обходит кэширование, что означает ненужные задержки и использование полосы пропускания всякий раз, когда изображение не меняется между представлениями. Потенциально заполнит кеш браузера (и любые промежуточные кеши) множеством копий одного и того же изображения! Также требуется изменение URL изображения.
Когда использовать: Используйте, когда изображение постоянно меняется, например, для прямой трансляции с веб-камеры. Если вы используете этот метод, убедитесь, что сами изображения используются с
Cache-control: no-cache
заголовками HTTP !!! (Часто это можно настроить с помощью файла .htaccess). В противном случае вы будете постепенно заполнять кеши старыми версиями изображения!(2) Добавьте параметр запроса к URL, который изменяется только тогда, когда файл делает, например:
(Это PHP-код на стороне сервера, но важным моментом здесь является то, что строка имени? M = [время последнего изменения файла] добавляется к имени файла).
Плюсы: 100% надежность, быстрота и простота понимания и реализации, а также превосходное сохранение преимуществ кэширования.
Минусы: Требуется изменить URL изображения. Кроме того, немного больше работы для сервера - он должен получить доступ к времени последней модификации файла. Кроме того, требуется информация на стороне сервера, поэтому она не подходит для решения исключительно на стороне клиента для проверки обновленного изображения.
Когда использовать: Когда вы хотите кэшировать изображения, но, возможно, потребуется периодически обновлять их на конце сервера без изменения самого имени файла. И когда вы можете легко убедиться, что правильная строка запроса добавлена к каждому экземпляру изображения в вашем HTML.
(3) Подайте ваши изображения с заголовком
Cache-control: max-age=0, must-revalidate
и добавьте в URL уникальный идентификатор фрагмента, разрушающего memcache , например:Идея заключается в том, что заголовок элемента управления кешем помещает изображения в кеш браузера, но сразу же помечает их как устаревшие, поэтому при каждом их повторном отображении браузер должен проверять сервер, чтобы убедиться, что они изменились. Это гарантирует, что HTTP-кеш браузера всегда возвращает самую последнюю копию изображения. Тем не менее, браузеры часто используют копию изображения в памяти, если она у него есть, и даже не проверяют свой HTTP-кеш в этом случае. Чтобы предотвратить это, используется идентификатор фрагмента: Сравнение изображений в памяти
src
включает идентификатор фрагмента, но он отбрасывается перед запросом кеша HTTP. (Так, например,image.jpg#A
иimage.jpg#B
оба могут отображаться изimage.jpg
записи в HTTP-кэше браузера, ноimage.jpg#B
никогда не будет отображаться с использованием сохраненных в памяти данных изображения с моментаimage.jpg#A
последнего отображения).Плюсы: правильно использует механизмы кэширования HTTP и использует кэшированные изображения, если они не изменились. Работает для серверов, которые задушивают строку запроса, добавленную к статическому URL-адресу изображения (поскольку серверы никогда не видят идентификаторы фрагментов - они предназначены только для собственного использования браузерами).
Минусы: полагается на несколько сомнительное (или, по крайней мере, плохо документированное) поведение браузеров в отношении изображений с идентификаторами фрагментов в их URL-адресах (однако, я успешно протестировал это в FF27, Chrome33 и IE11). По-прежнему отправляет запрос на повторную проверку на сервер для каждого просмотра изображения, что может быть излишним, если изображения меняются очень редко и / или задержка является большой проблемой (поскольку вам нужно дождаться ответа на повторную проверку, даже если кэшированное изображение все еще исправно) , Требуется изменить URL-адреса изображений.
Когда использовать: Используйте, когда изображения могут часто меняться или когда клиент должен периодически обновлять их без участия сценариев на стороне сервера, но в тех случаях, когда вам все еще нужно преимущество кэширования. Например, опрос живой веб-камеры, которая обновляет изображение нерегулярно каждые несколько минут. В качестве альтернативы используйте вместо (1) или (2), если ваш сервер не разрешает строки запросов для статических URL-адресов изображений.
(4) Принудительно обновите определенное изображение, используя Javascript, сначала загрузив его в скрытое,
<iframe>
а затем вызвавlocation.reload(true)
кадры iframecontentWindow
.Шаги:
Загрузите изображение для обновления в скрытый фрейм. Это всего лишь шаг настройки - при желании его можно сделать задолго до фактического обновления. Даже не имеет значения, если изображение не загружается на этом этапе!
Как только это будет сделано, удалите все копии этого изображения на своих страницах или в любом месте в любых узлах DOM (даже вне страницы, хранящиеся в переменных javascript). Это необходимо, поскольку в противном случае браузер может отображать изображение из устаревшей копии в памяти (особенно это делает IE11): перед обновлением кэша HTTP необходимо убедиться, что все копии в памяти очищены. Если другой код javascript выполняется асинхронно, вам также может потребоваться предотвратить создание этим кодом новых копий обновляемого изображения.
Вызов
iframe.contentWindow.location.reload(true)
. Вtrue
силах перепускной кэша, перезарядка непосредственно с сервера и перезапись существующих кэшированных копий.После завершения перезагрузки восстановите пустые изображения. Теперь они должны отображать свежую версию с сервера!
Для изображений того же домена вы можете загрузить изображение непосредственно в iframe. Для междоменных изображений вы должны вместо этого загрузить страницу HTML из своего домена, которая содержит изображение в
<img>
теге, в противном случае вы получите ошибку «Отказано в доступе» при попытке вызоваiframe.contentWindow.reload(...)
.Плюсы: работает так же, как функция image.reload (), которую вы хотели бы иметь в DOM! Позволяет кэшировать изображения в обычном режиме (даже с датами истечения срока действия в будущем, если вы этого хотите, что позволяет избежать частой повторной проверки). Позволяет обновить определенное изображение, не изменяя URL-адреса этого изображения на текущей странице или на любых других страницах, используя только код на стороне клиента.
Минусы: опирается на Javascript. Не гарантируется 100% правильная работа в каждом браузере (хотя я успешно проверил это в FF27, Chrome33 и IE11). Очень сложный по сравнению с другими методами.
Когда использовать: Если у вас есть коллекция статичных изображений, которые вы хотели бы кэшировать, но вам все равно нужно время от времени обновлять их и получать немедленную визуальную информацию о том, что произошло обновление. (Особенно, когда просто не обновляется вся страница браузера, как, например, в некоторых веб-приложениях, построенных на AJAX). И когда методы (1) - (3) неосуществимы, потому что (по какой-либо причине) вы не можете изменить все URL-адреса, которые потенциально могут отображать изображение, которое вам необходимо обновить. (Обратите внимание, что при использовании этих 3 методов изображение будет обновлено, но если другая страница затем попытается отобразить это изображение без соответствующей строки запроса или идентификатора фрагмента, вместо этого может отобразиться более старая версия).
Детали реализации этого сказочно надежного и гибкого способа приведены ниже:
Предположим, что ваш сайт содержит пустой 1x1 пиксель .gif по пути URL
/img/1x1blank.gif
, а также имеет следующий однострочный PHP-скрипт (требуется только для применения принудительного обновления к междоменным изображениям и может быть переписан на любом языке сценариев на стороне сервера). , конечно) по пути URL/echoimg.php
:Затем, вот реалистичная реализация того, как вы можете сделать все это в Javascript. Это выглядит немного сложно, но комментариев много, и важной функцией является просто forceImgReload () - первые два просто пустые и непустые изображения, и должны быть спроектированы для эффективной работы с вашим собственным HTML, поэтому кодируйте их как работает лучше для вас; большая часть осложнений в них может быть ненужной для вашего сайта:
Затем, чтобы принудительно обновить изображение, расположенное в том же домене, что и ваша страница, вы можете просто сделать:
Чтобы обновить изображение из другого места (междоменный):
Более сложное приложение может состоять в том, чтобы перезагрузить изображение после загрузки новой версии на ваш сервер, подготовив начальный этап процесса перезагрузки одновременно с загрузкой, чтобы минимизировать видимую задержку перезагрузки для пользователя. Если вы выполняете загрузку через AJAX, а сервер возвращает очень простой массив JSON [success, width, height], тогда ваш код может выглядеть примерно так:
Последнее замечание: хотя эта тема посвящена изображениям, она потенциально применима и к другим видам файлов или ресурсов. Например, предотвращение использования устаревших сценариев или CSS-файлов или, возможно, даже обновление обновленных PDF-документов (использование (4), только если настроено открытие в браузере). Метод (4) может потребовать некоторых изменений в вышеупомянутом javascript, в этих случаях.
источник
image.jpg#123
наimage.jpg#124
(или как угодно, до тех пор, пока бит после «#» не изменится). Не могли бы вы уточнить, что именно вы перезагружаете и почему?contentWindow
через javascript для выполненияreload(true)
вызова, который является критической частью метода ... так что нет, method (4) ) не будет работать для междоменного контента. Хорошо подмечено; Я обновлю «Минусы», чтобы включить это.Как альтернатива ...
...Кажется, что...
... достаточно, чтобы обмануть кеш браузера, не обходя никакие восходящие кеши, при условии, что вы вернули правильные
Cache-Control
заголовки. Хотя вы можете использовать ...... вы теряете преимущества заголовков
If-Modified-Since
илиIf-None-Match
, так что-то вроде ...... должен предотвратить повторную загрузку браузером всего изображения, если оно фактически не изменилось. Протестировано и работает на IE, Firefox и Chrome. Досадно, что это не работает в Safari, если вы не используете ...
... хотя это все же может быть предпочтительнее, чем заполнение вышестоящих кешей сотнями идентичных изображений, особенно когда они работают на вашем собственном сервере. ;-)
Обновление (2014-09-28): в настоящее время похоже, что
Cache-Control: no-store
это необходимо и для Chrome.источник
src
атрибутом, поэтому добавление уникального идентификатора фрагмента гарантирует, что изображение не будет просто извлечено из памяти. Но идентификаторы фрагментов не отправляются как часть HTTP-запросов, поэтому обычный HTTP-кеш будет использоваться как обычно. Вот почему эта техника работает.Cache-Control: max-age=0, must-revalidate
хорошо для меня?newImage.src = "http://localhost/image.jpg#" + i++;
После создания нового образа вы удаляете старый образ из DOM и заменяете его новым?
Вы можете получать новые изображения при каждом вызове updateImage, но не добавлять их на страницу.
Есть несколько способов сделать это. Нечто подобное будет работать.
После того, как все заработало, если проблемы все еще существуют, это, вероятно, проблема с кэшированием, о которой говорят другие ответы.
источник
Одним из ответов является хакерское добавление некоторого параметра запроса get, как было предложено.
Лучший ответ - добавить пару дополнительных параметров в заголовок HTTP.
Предоставляя дату в прошлом, она не будет кэшироваться браузером.
Cache-Control
был добавлен в HTTP / 1.1, а тег must-revalidate указывает на то, что прокси никогда не должны обслуживать старое изображение даже при смягчающих обстоятельствах, и это наPragma: no-cache
самом деле не является необходимым для современных современных браузеров / кешей, но может помочь с некоторыми неработающими старыми реализациями.источник
У меня было требование: 1) не могу добавить любой
?var=xx
к изображению 2) он должен работать междоменныйМне очень нравится вариант № 4 в этом ответе с одним, но:
Мой быстрый и грязный путь:
iframe.contentWindow.location.reload(true);
Вот
Да, я знаю, setTimeout ... Вы должны изменить это на надлежащие события загрузки.
источник
Тогда ниже в некотором JavaScript
И вот что происходит, когда изображение загружается, планирует его перезагрузку через 1 секунду. Я использую это на странице с домашними камерами безопасности различного типа.
источник
В итоге я заставил сервер сопоставить любой запрос на изображение в этом каталоге с источником, который я пытался обновить. Затем мой таймер добавил число в конец имени, чтобы DOM увидел его как новое изображение и загрузил его.
Например
запросит тот же код генерации изображения, но он будет выглядеть как разные изображения в браузере.
источник
источник
../showImage.phpFri May 01 2015 17:34:18 GMT+0200 (Mitteleuropäische Sommerzeit)
это правильное имя файла ... По крайней мере, это то, что он пытается загрузить ...path='../showImage.php';
наpath='../showImage.php?';
установить свой собственный src в качестве src.
источник
Попробуйте использовать бесполезную строку запроса, чтобы сделать ее уникальной ссылкой:
источник
Крупный основанный на коде Играет в # 4, в приведенном ниже примере , что упрощает код отличный бит , используя
document.write
вместо того , чтобыsrc
вiframe
поддержки CORS. Также фокусируется только на очистке кеша браузера, а не на перезагрузке каждого изображения на странице.Ниже написано
typescript
и использует библиотеку обещанийangular
$ q , просто fyi, но она должна быть достаточно простой для переноса на vanilla javascript. Метод предназначен для жизни внутри машинописного класса.Возвращает обещание, которое будет выполнено после завершения перезагрузки iframe. Не проверено, но у нас хорошо работает.
источник
+ encodeURI(src) +
для правильного выходаsrc
вiframe
.Следующий код полезен для обновления изображения при нажатии кнопки.
источник
Я решил эту проблему, отправив данные обратно через сервлет.
Затем со страницы вы просто даете ему сервлет с некоторыми параметрами, чтобы получить правильный файл изображения.
источник
Вот мое решение. Это очень просто. Кадровое планирование может быть лучше.
источник
Нет необходимости в
new Date().getTime()
махинациях. Вы можете обмануть браузер, имея невидимое фиктивное изображение и используя jQuery .load (), затем каждый раз создавая новое изображение:источник
Простое решение: добавьте этот заголовок к ответу:
Почему это работает, ясно объяснено на этой официальной странице: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
Это также объясняет, почему
no-cache
не работает.Другие ответы не работают, потому что:
Caching.delete
о новом кеше, который вы можете создать для автономной работы, см .: https://web.dev/cache-api-quick-guide/Фрагменты, использующие # в URL, не работают, потому что # говорит браузеру не отправлять запрос на сервер.
Работает кеш-буфер со случайной частью, добавленной в URL, но также заполняет кеш браузера. В своем приложении я хотел загружать изображение размером 5 МБ каждые несколько секунд с веб-камеры. Это займет всего час или меньше, чтобы полностью заморозить ваш компьютер. Я до сих пор не знаю, почему кеш браузера не ограничен разумным максимумом, но это определенно недостаток.
источник
Я улучшил сценарий от AlexMA для отображения моей веб-камеры на веб-странице, которая периодически загружает новое изображение с тем же именем. У меня были проблемы, из-за которых изображение иногда мерцало из-за разбитого изображения или неполного (вверх) загруженного изображения. Чтобы предотвратить мерцание, я проверяю естественную высоту изображения, поскольку размер изображения с моей веб-камеры не изменился. Только если высота загруженного изображения соответствует высоте исходного изображения, полное изображение будет отображаться на странице.
источник
Я использовал приведенную ниже концепцию: сначала связать изображение с ложным (буферным) URL, а затем - с действительным URL.
Таким образом, я заставляю браузер обновляться с действительным URL.
источник