Как перезагрузить / обновить элемент (изображение) в jQuery

262

Можно ли перезагрузить изображение с идентичным именем файла с сервера с помощью jQuery?

Например, у меня есть изображение на странице, однако физическое изображение может меняться в зависимости от действий пользователя. Обратите внимание, это не означает, что имя файла изменяется, а сам файл.

то есть:

  • Пользователь просматривает изображение на странице по умолчанию
  • Пользователь загружает новое изображение
  • Изображение по умолчанию на странице не изменяется (я полагаю, это связано с тем, что имя файла идентично, браузер использует кэшированную версию)

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

$("#myimg").attr("src", "/myimg.jpg");

В документации jQuery функция «load» была бы идеальной, если бы у нее был метод запуска события по умолчанию, а не привязка функции обратного вызова к успешной / полной загрузке элемента.

Любая помощь очень ценится.

Алексис Абриль
источник
1
@ Алексис, ваша проблема в том, что изображение кэшируется в браузере и не будет обновляться после его изменения на сервере?
Джей
1
@ Jeerose, я считаю, что это проблема, поскольку файл действительно изменяется (то же имя файла) и отражается на странице, если вы делаете полное обновление страницы.
Алексис Абриль

Ответы:

551

Похоже, это ваш браузер кэширует изображение (которое, как я теперь заметил, вы написали в своем вопросе). Вы можете заставить браузер перезагрузить изображение, передав дополнительную переменную следующим образом:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
сойка
источник
1
Добавление переменной строки запроса полностью пришло мне в голову. Это решило проблему, и изображение теперь перезагружается по запросу.
Алексис Абриль
45
гангста, любите его
Дейв Джеллисон
4
Это работает, и это хороший обходной путь, но все же обходной путь! Нет ли другого способа получить изображение, которое говорит браузеру забыть о кэшированном?
Spuas
У меня очень требовательная веб-камера, которая, кажется, запрещает любые запросы статических изображений, которые содержат параметры. Тьфу. Это отличное решение в противном случае.
dangowans
3
@TomasGonzalez B / C есть есть шанс получить столкновение с random, и никогда не должно быть с , Dateесли вы не на самом деле очень быстро. ; ^) Получение даты на клиенте не так ресурсоемко, и вы можете повторно использовать столько изображений, сколько вам нужно вытащить одновременно, поэтому перейдите к шагу 4. Прибыль.
Ерф
57

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

$("#myimg").attr("src", "/myimg.jpg?timestamp=" + new Date().getTime());

При следующей загрузке отметка времени будет установлена ​​на текущее время, а URL-адрес будет другим, поэтому браузер выполняет GET для изображения вместо использования кэшированной версии.

Калеб Бразе
источник
2
Это работало у меня годами, но сегодня мой сервер изображений (не контролируемый мной) начал возвращать неработающую ссылку, если имя файла не точное. Если у кого-то есть другой обходной путь, он будет очень признателен. К сожалению, каждый ответ в этой теме является вариацией этого.
Felwithe
@felwithe, может быть, этот сервер ищет только расширение в конце запроса? Таким образом, вы можете попробовать проверить этот подход: imagename.jpg?t=1234567&q=.jpgилиimagename.jpg#t1234567.jpg
FlameStorm
26

Это может быть одной из двух проблем, которые вы упоминаете сами.

  1. Сервер кеширует изображение
  2. JQuery не запускается или по крайней мере не обновляет атрибут

Если честно, я думаю, что это номер два. Было бы намного проще, если бы мы могли увидеть еще jQuery. Но для начала попробуйте сначала удалить атрибут, а затем установить его снова. Просто чтобы посмотреть, поможет ли это:

$("#myimg").removeAttr("src").attr("src", "/myimg.jpg");

Даже если это работает, выложите некоторый код, так как это не оптимально, IMO :-)

Kordonme
источник
@ Kordonme, это где кто-то комментирует "плохой" jQuery? (Я шучу, я шучу);)
Джей
@Kordonme, это на самом деле хранится в обработчике событий и на данный момент является единственной строкой кода. Я добавил предупреждение перед этой строкой, чтобы убедиться, что событие действительно запускается. Событие происходит без ошибок.
Алексис Абриль
3
У меня очень требовательная веб-камера, которая, кажется, запрещает любые запросы статических изображений, которые содержат параметры. Тьфу. Это отличное решение для моего уникального случая. Спасибо.
dangowans
Это лучший ответ, если вы не хотите / нуждаетесь в остаточных параметрах
RafaSashi
Спасибо, это помогло (это только кэшировало это для меня в Chrome)
Даниэль Реш,
14

с одной строкой, не беспокоясь о жестком кодировании изображения src в javascript (спасибо jerose за идеи:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
Radu
источник
13
Просто будьте осторожны, потому что это будет бесконечно добавлять все больше и больше символов в конец URL
Alfo
9

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

//refresh the image every 60seconds
var xyro_refresh_timer = setInterval(xyro_refresh_function, 60000);

function xyro_refresh_function(){
//refreshes an image with a .xyro_refresh class regardless of caching
    //get the src attribute
    source = jQuery(".xyro_refresh").attr("src");
    //remove previously added timestamps
    source = source.split("?", 1);//turns "image.jpg?timestamp=1234" into "image.jpg" avoiding infinitely adding new timestamps
    //prep new src attribute by adding a timestamp
    new_source = source + "?timestamp="  + new Date().getTime();
    //alert(new_source); //you may want to alert that during developement to see if you're getting what you wanted
    //set the new src attribute
    jQuery(".xyro_refresh").attr("src", new_source);
}
разрывать
источник
6

Это прекрасно работает! однако, если вы перезагрузите src несколько раз, отметка времени также будет объединена с URL. Я изменил принятый ответ, чтобы справиться с этим.

$('#image_reload_button').on('click', function () {
    var img = $('#your_image_selector');
    var src = img.attr('src');
    var i = src.indexOf('?dummy=');
    src = i != -1 ? src.substring(0, i) : src;

    var d = new Date();
    img.attr('src', src + '?dummy=' + d.getTime());
});
Каспер Тэйманс
источник
3

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

function imageUploadComplete () {
    $("#image_container").html("<img src='" + newImageUrl + "'>");
}
Матти лира
источник
2

Иногда на самом деле решение вроде -

$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));

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

$("#Image").attr("src", "dummy.jpg");
$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));
Кульбхушан Часкар
источник
1

Использование «#» в качестве разделителя может быть полезным

Мои изображения хранятся в «скрытой» папке над «www», поэтому доступ к ним имеют только зарегистрированные пользователи. По этой причине я не могу использовать обычные, <img src=/somefolder/1023.jpg>но я отправляю запросы на сервер как, <img src=?1023>и он отвечает, отправляя обратно изображение, сохраненное под именем «1023».

Приложение используется для обрезки изображения, поэтому после Ajax-запроса обрезать изображение оно изменяется как содержимое на сервере, но сохраняет свое первоначальное имя. Чтобы увидеть результат обрезки, после завершения запроса ajax первое изображение удаляется из DOM, и новое изображение вставляется с тем же именем <img src=?1023>.

Чтобы избежать обналичивания, я добавляю к запросу тег «time» с добавлением «#», чтобы он выглядел как <img src=?1023#1467294764124>. Сервер автоматически отфильтровывает хеш-часть запроса и правильно отвечает, отправляя обратно мое изображение, сохраненное как «1023». Таким образом, я всегда получаю последнюю версию изображения без особого декодирования на стороне сервера.

user3506298
источник
1
Зачем проходить через все эти неприятности, чтобы служить образу? Похоже, бессмысленная
стычка
0

Возможно, мне придется перезагрузить источник изображения несколько раз. Я нашел решение с Lodash, которое хорошо работает для меня:

$("#myimg").attr('src', _.split($("#myimg").attr('src'), '?', 1)[0] + '?t=' + _.now());

Существующая временная метка будет обрезана и заменена новой.

SLP
источник
-1

Основано на ответе @kasper Taeymans.

Если вам просто нужно перезагрузить образ (не заменить src на что-то новое), попробуйте:

$(function() {
  var img = $('#img');

  var refreshImg = function(img) {
    // the core of answer is 2 lines below
    var dummy = '?dummy=';
    img.attr('src', img.attr('src').split(dummy)[0] + dummy + (new Date()).getTime());

    // remove call on production
    updateImgVisualizer();
  };


  // for display current img url in input
  // for sandbox only!
  var updateImgVisualizer = function() {
    $('#img-url').val(img.attr('src'));
  };

  // bind img reload on btn click
  $('.img-reloader').click(function() {
    refreshImg(img);
  });

  // remove call on production
  updateImgVisualizer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="img" src="http://dummyimage.com/628x150/">


<p>
  <label>
    Current url of img:
    <input id="img-url" type="text" readonly style="width:500px">
  </label>
</p>

<p>
  <button class="img-reloader">Refresh</button>
</p>

userlond
источник
-2

Я просто делаю это в HTML:

<script>
    $(document).load(function () {
        d = new Date();
        $('#<%= imgpreview.ClientID %>').attr('src','');
    });
</script>

И перезагрузите изображение в коде так:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        image.Src = "/image.jpg"; //url caming from database
    }

}

FTheGodfather
источник
1
Перезагрузка страницы и настройка в asp.NET WebForms не совсем здесь обсуждаются.
Джонас Стенсвед