Я знаю, что есть много способов предотвратить кеширование изображений (например, с помощью тегов META), а также есть несколько хороших уловок, чтобы гарантировать, что текущая версия изображения отображается при каждой загрузке страницы (например, image.jpg? X = timestamp ), но есть ли способ фактически очистить или заменить изображение в кеше браузеров, чтобы ни один из вышеперечисленных методов не требовался?
В качестве примера предположим, что на странице 100 изображений, и эти изображения называются "01.jpg", "02.jpg", "03.jpg" и т. д. Если изображение "42.jpg" заменено, будет есть ли способ заменить его в кеше, чтобы "42.jpg" автоматически отображал новое изображение при последующих загрузках страницы? Я не могу использовать метод тега META, потому что мне нужно все, что ISN "T заменено, чтобы оставаться в кэше, и я не могу использовать метод временной метки, потому что я не хочу, чтобы ВСЕ изображения перезагружались каждый раз, когда страница нагрузки.
Я ломал голову и искал в Интернете способ сделать это (желательно через javascript), но безуспешно. Какие-либо предложения?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Причина использования трюка? X = timestamp заключается в том, что это единственный способ сделать это для каждого изображения. Это или динамически генерировать имена изображений и указывать на приложение, которое выводит изображение.
Я предлагаю вам выяснить, на стороне сервера, если изображение было изменено / обновлено, и если да, то выведите свой тег с помощью трюка? X = timestamp, чтобы принудительно создать новое изображение.
Если вы пишете страницу динамически, вы можете добавить к URL-адресу метку времени последнего изменения:
<img src = "image.jpg?lastmod=12345678" ...
как насчет <img src = "image.jpg?<?php echo filemtime('image.jpg') ?>", динамичнее конечно!
<meta> абсолютно неактуален. Фактически, вам вообще не следует пытаться использовать его для управления кешем (к тому времени, когда что-либо читает содержимое документа, оно уже кэшируется).
В HTTP каждый URL независим. Что бы вы ни делали с HTML-документом, это не применимо к изображениям.
Для управления кешированием вы можете изменять URL-адреса каждый раз, когда изменяется их содержимое. Если вы время от времени обновляете изображения, позволяйте им кэшироваться навсегда и используйте новое имя файла (с версией, хешем или датой) для нового изображения - это лучшее решение для долгоживущих файлов.
Если ваше изображение меняется очень часто (каждые несколько минут или даже при каждом запросе), отправьте Cache-control: no-cache или Cache-control: max-age=xx, где хх - количество секунд, в течение которых изображение остается «свежим».
Случайный URL для недолговечных файлов - плохая идея. Он загрязняет кеши бесполезными файлами и заставляет быстрее очищать полезные файлы.
Если у вас есть Apache и mod_headers или mod_expires, создайте файл .htaccess с соответствующими правилами.
<Files ~ "-nocache\.jpg">
Header set Cache-control "no-cache"
</Files>
Вышеуказанное сделает файлы *-nocache.jpg не кэшируемыми.
Вы также можете передавать изображения через PHP-скрипт (по умолчанию они ужасно доступны;)
Измените ETAG для изображения.
Это не поможет, если браузер не проверяет кешированное изображение.
с кешированием браузера никогда не бывает универсального решения, подходящего для всех. это лишь одно из тех, что вы предложили.
Я уверен, что большинство браузеров уважают HTTP-заголовок Последнее изменение. Отправьте их и запросите новое изображение. Он будет кэширован браузером, если строка Last-Modified не изменится.
In the event that an image is re-uploaded, is there a way to CLEAR or REPLACE the previously cached image client-side? In my example above, the goal is to make the browser forget what "42.jpg" is
Вы ведь используете firefox?
ToolsClear Private DataCache.:-)
Если серьезно, я никогда не слышал о существовании такой вещи и сомневаюсь, что для этого есть API. Я не могу себе представить, что со стороны разработчиков браузеров было бы хорошей идеей позволить вам копаться в их кеше, и я не вижу никакой мотивации для того, чтобы они когда-либо реализовали такую функцию.
I CANNOT use the META tag method OR the timestamp method, because I want all of the images cached under normal circumstances.
Почему вы не можете использовать метку времени (или etag, что одно и то же)? Помните, что вы должны использовать метку времени самого файла изображения, а не только Time.Now.
Ненавижу сообщать плохие новости, но у тебя нет других вариантов.
Если изображения не меняются, метка времени не изменится, поэтому все будет кэшироваться «при нормальных обстоятельствах». Если изображения действительно изменятся, они получат новую временную метку (которая понадобится им для целей кеширования), но тогда эта временная метка останется действительной навсегда, пока кто-то снова не заменит изображение.
Нет, невозможно принудительно удалить файл в кеше браузера ни веб-сервером, ни чем-либо, что вы можете поместить в отправляемые файлы. Кеш браузера принадлежит браузеру и контролируется пользователем.
Следовательно, вы должны относиться к каждому файлу и каждому URL-адресу как к драгоценному ресурсу, которым следует тщательно управлять.
Поэтому предложение porneL о версиях файлов изображений кажется лучшим долгосрочным ответом. ETAG используется в нормальных условиях, но, может быть, ваши усилия свели его на нет? Попробуйте изменить ETAG, как предложено.
Если изменение имени файла изображения невозможно, используйте переменную сеанса на стороне сервера и функцию javascript window.location.reload(). Следующее:
После завершения загрузки:
Session("reload") = "yes"
На page_load:
If Session("reload") = "yes" Then
Session("reload") = Nothing
ClientScript.RegisterStartupScript(Me.GetType), "ReloadImages", "window.location.reload();", True)
End If
Это позволяет клиентскому браузеру обновляться только один раз, потому что переменная сеанса сбрасывается после одного события.
Надеюсь это поможет.
См. http://en.wikipedia.org/wiki/URI_scheme
Обратите внимание, что вы можете указать уникальное имя пользователя: пароль @ combo в качестве префикса к доменной части uri. В своих экспериментах я обнаружил, что включение этого с поддельным идентификатором (или паролем, как я предполагаю) приводит к обработке ресурса как уникального - таким образом нарушая кеширование по вашему желанию.
Просто используйте временную метку в качестве имени пользователя, и, насколько я могу судить, сервер игнорирует эту часть uri, пока не включена аутентификация.
Кстати, я также не мог использовать описанные выше приемы с проблемой кеширования значков маркеров карты Google, с которой я столкнулся, когда трюк? Param = timestamp работал, но вызывал проблемы с исчезновением наложений. Никогда не мог понять, почему это происходит, но пока все хорошо, используя этот метод. В чем я не уверен, так это в том, что передача поддельных учетных данных отрицательно скажется на производительности сервера. Если кто-нибудь знает, мне было бы интересно узнать, поскольку я еще не занимаюсь крупносерийным производством.
Пожалуйста, сообщите о своих результатах.
Это ужасная идея передавать учетные данные в URL-адресе только для того, чтобы нарушить кеширование. Пожалуйста, не делайте этого.
Добавьте URL-адрес изображения, как это
"image1.jpg?" + DateTime.Now.ToString ("ddMMyyyyhhmmsstt");
Просто добавьте случайную строку в строку запроса
Спасибо
Раджу Джетла
На самом деле это не обновляет кеш изображений. Он просто заставляет браузер думать, что это новое изображение. С помощью этого метода, если я проверю кеш хрома, я могу увидеть более 12 изображений одного и того же изображения. Установка Cache-Control на ответ сервера для меня - лучшее решение, а не взлом. В идеале вы хотите, чтобы браузер кэшировал изображение, просто обновляйте его при изменении.
Чтобы заменить кеш для изображения, вы можете сохранить на стороне сервера некоторое значение версии, а при загрузке изображения просто отправьте это значение вместо отметки времени. Когда ваше изображение будет изменено, измените его версию.
Вопреки тому, что было сказано в некоторых других ответах, существует ЯВЛЯЕТСЯ способ для клиентского javascript заменить кешированное изображение. Уловка состоит в том, чтобы создать скрытый <iframe>, установить его атрибут src на URL-адрес изображения, дождаться его загрузки, а затем принудительно перезагрузить его, вызвав location.reload(true). Это обновит кешированную копию изображения. Затем вы можете заменить элементы <img> на своей странице (или перезагрузить страницу), чтобы увидеть обновленную версию изображения.
(Небольшое предостережение: при обновлении отдельных элементов <img> и если обновленный образ имеется более чем у одного, вы должны очистить или удалить их ВСЕ, а затем заменить или сбросить их. Если вы делаете это по одному. Во-первых, некоторые браузеры скопируют версию изображения в памяти из других тегов, и в результате вы можете не увидеть обновленное изображение, несмотря на то, что оно находится в кеше).
Я разместил код для такого обновления здесь.
Я попробовал что-то до смешного простое:
Перейдите в папку FTP на веб-сайте и переименуйте папку IMG в IMG2. Обновите свой сайт, и вы увидите, что изображения будут отсутствовать. Затем переименуйте папку IMG2 обратно в IMG, и все готово, по крайней мере, у меня это сработало в Safari.
Это приведет к обновлению кеша только тех клиентов, которые обращались к странице, когда изображение было перемещено и 404 загружено. OP, вероятно, искал что-то, что будет каскадно для всех пользователей независимо от момента времени.
Просто отметить, что только то, что вы создали IMG2, не означает, что IMG был удален из пользовательского кеша. Это помимо того, что заявил «Компас». Это также проблема переименования изображения при каждой его загрузке. Использование кэш-памяти становится все более популярным, как топ-модель, предлагающая 2 доллара _... ну вы понимаете.
Вы можете добавить к изображению случайное число, как если бы ему дали новую версию. Я реализовал аналогичную логику, и она отлично работает.
<script>
var num = Math.random();
var imgSrc= "image.png?v = "+num;
$(function() {
$('#imgID').attr("src", imgSrc);
})
</script>
попробуйте решения ниже,
myImg.src = "http: //localhost/image.jpg?" + новая дата (). getTime ();
Вышеупомянутые решения работают для меня :)
Попробуйте этот фрагмент кода:
var url = imgUrl? + Math.random();
Это гарантирует, что каждый запрос уникален, поэтому вы всегда будете получать последнее изображение.
Обычно я делаю то же, что сказал нам @Greg, и у меня есть для этого функция:
function addMagicRefresh(url)
{
var symbol = url.indexOf('?') == -1 ? '?' : '&';
var magic = Math.random()*999999;
return url + symbol + 'magic=' + magic;
}
Это будет работать, поскольку ваш сервер принимает это, и вы не используете «волшебный» параметр по-другому.
Я надеюсь, что это помогает.
@ user3304007 это именно моя цель с кодом выше. Поскольку мой пользователь заменяет изображение и мой URL-адрес изображения, он всегда ОДИНАКОВ. Использование отметки времени не обновит мое изображение. Так что это не на любителя, это по дизайну.
Поскольку большинство, если не все, ответы и комментарии здесь являются копиями частей вопроса или достаточно близкими, я брошу свои 2 цента.
Я просто хочу отметить, что даже если есть способ, реализовать его будет сложно. Логика этого нас заманивает. С логической позиции, говоря браузеру, чтобы он заменял кэшированные изображения для каждого измененного изображения в списке, поскольку определенная дата является идеальной, НО ... Когда вы удалите список и как вы узнаете, есть ли у всех последняя версия, которая будет посещать очередной раз?
Итак, мое первое «предложение», о котором просил ОП, - это теория списков.
Как я вижу это:
A.) Имейте список, в котором могут храниться наши динамические и измененные вручную URL-адреса изображений.
B.) Установите дату окончания, когда улов будет сброшен, и список будет обрезан независимо.
C.0) Контрольный список при входе на сайт по сравнению с браузером через i-фрейм, который можно запустить в фоновом режиме с более коротким заголовком кеша, установленным для повторного кеширования их всех по самой дальней дате в списке или чему-то в этом роде.
C.1) Используя запрос Iframe или ajax / xhr, я думаю, вы могли бы перебрать каждое изображение списка, обновляя страницу, чтобы показать другое изображение и проверить кеш по его собственной измененной дате. Таким образом, при загрузке этого изображения используйте серверную часть, чтобы определить, не является ли это последним изображением при загрузке, и перейдите к следующему изображению.
C.1a) Это будет означать, что нашему списку может потребоваться больше информации для каждого изображения, и я думаю, что очевидным является возможная необходимость некоторого серверного скрипта для настройки заголовков в соответствии с требованиями каждого изображения, чтобы минимизировать шаги повторного кэширования измененного сайта. изображений.
Моим вторым «предложением» было бы уведомить пользователя об изменениях и дать ему указание очистить кеш. (Осторожно, по возможности удаляйте только изображения и файлы или предупреждайте их об удалении данных в процессе)
P.S. Это просто образованное представление. Быстрая теория. Если / когда я это сделаю, я выложу финал. Вероятно, не здесь, потому что для этого потребуется сценарий на стороне сервера. Это, по крайней мере, предложение, не упомянутое в вопросе ОП, которое, по его словам, он уже пробовал.
Похоже, что в основе вашего вопроса - как вытащить старую версию изображения из кеша. У меня был успех, просто сделав новый вызов и указав в заголовке, чтобы не извлекать из кеша. Вы просто выбрасываете это, как только вы его извлекаете, но в этот момент в кеше браузера должно быть обновленное изображение.
var headers = new Headers()
headers.append('pragma', 'no-cache')
headers.append('cache-control', 'no-cache')
var init = {
method: 'GET',
headers: headers,
mode: 'no-cors',
cache: 'no-cache',
}
fetch(new Request('path/to.file'), init)
Однако важно понимать, что это влияет только на браузер, из которого вызывается. Если вам нужна новая версия файла для любого браузера после замены изображения, это нужно будет сделать через конфигурацию сервера.
Вот решение, использующее функцию PHP filemtime ():
<?php
$addthis = filemtime('myimf.jpg');
?>
<img src = "myimg.jpg?"<?= $addthis;?> >
Использование времени изменения файла в качестве параметра заставит его читать из кэшированной версии до тех пор, пока файл не будет изменен. Этот подход лучше, чем использование, например, случайное число, так как кеширование все равно будет работать, если файл не изменился.
После долгих испытаний решение я нашел следующим образом.
1- Я создаю временную папку для копирования изображений с именем добавление времени () .. (если папка существует, я удаляю содержимое)
2- загрузить изображения из этой временной локальной папки
таким образом я всегда убеждаюсь, что браузер никогда не кэширует изображения и работает на 100% правильно.
if (!is_dir(getcwd(). 'articulostemp')){
$oldmask = umask(0);mkdir(getcwd(). 'articulostemp', 0775);umask($oldmask);
}else{
rrmfiles(getcwd(). 'articulostemp');
}
foreach ($images as $image) {
$tmpname = time().'-'.$image;
$srcimage = getcwd().'articulos/'.$image;
$tmpimage = getcwd().'articulostemp/'.$tmpname;
copy($srcimage,$tmpimage);
$urlimage='articulostemp/'.$tmpname;
echo ' <img loading = "lazy" src = "'.$urlimage.'"/> ';
}
это лучший ответ, который я считаю, потому что он по-прежнему позволяет браузеру кэшировать.