Jak ponownie załadować / odświeżyć element (obraz) w jQuery


262

Czy jest możliwe ponowne załadowanie obrazu o identycznej nazwie pliku z serwera za pomocą jQuery?

Na przykład mam obraz na stronie, jednak obraz fizyczny może się zmienić w zależności od działań użytkownika. Uwaga: nie oznacza to zmiany nazwy pliku, ale sam plik.

to znaczy:

  • Użytkownik wyświetla obraz na stronie domyślnej
  • Użytkownik przesyła nowy obraz
  • Domyślny obraz na stronie nie zmienia się (zakładam, że wynika to z identyczności nazwy pliku, przeglądarka używa wersji buforowanej)

Ten sam problem występuje bez względu na to, jak często wywoływany jest poniższy kod.

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

W dokumentacji jQuery funkcja „load” byłaby idealna, gdyby miała domyślną metodę odpalenia zdarzenia, w przeciwieństwie do powiązania funkcji zwrotnej z udanym / całkowitym załadowaniem elementu.

Każda pomoc jest mile widziana.


1
@Alexis, czy masz problem z tym, że obraz jest buforowany w przeglądarce i nie aktualizuje się po zmianie na serwerze?
sójka

1
@jeerose, uważam, że jest to problem, ponieważ plik faktycznie się zmienia (ta sama nazwa pliku) i jest odzwierciedlany na stronie, jeśli wykonasz pełne odświeżenie strony.
Alexis Abril

Odpowiedzi:


551

Wygląda na to, że przeglądarka buforuje obraz (co teraz zauważam, że napisałeś w swoim pytaniu). Możesz zmusić przeglądarkę do ponownego załadowania obrazu, przekazując dodatkową zmienną, taką jak:

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

1
Dodanie zmiennej ciągu zapytania całkowicie przeszło mi przez myśl. To rozwiązało problem, a obraz ładuje się ponownie na żądanie.
Alexis Abril

45
wskazówka gangsta, uwielbiam to
Dave Jellison

4
Działa i jest to miłe obejście, ale wciąż obejście! Czy nie ma innego sposobu pobierania obrazu, który każe przeglądarce zapomnieć o pamięci podręcznej?
spuas

Mam naprawdę wybredną kamerę internetową, która wydaje się zabraniać wszelkich próśb o obrazy statyczne zawierające parametry. Ugh. W przeciwnym razie jest to świetne rozwiązanie.
dangowans

3
@TomasGonzalez B / c tam jest szansa na uzyskanie kolizji z random, i nie powinien nigdy być z Datechyba że jesteś naprawdę bardzo szybko. ; ^) Ustalenie daty na kliencie nie wymaga tak dużych zasobów, i możesz ponownie użyć tyle obrazów, ile potrzebujesz, aby pobrać jednocześnie, więc przejdź do kroku 4. Zysk.
ruffin

57

Prawdopodobnie nie jest to najlepszy sposób, ale w przeszłości rozwiązałem ten problem, po prostu dodając znacznik czasu do adresu URL obrazu za pomocą JavaScript:

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

Następnym razem, gdy się ładuje, znacznik czasu jest ustawiany na bieżącą godzinę, a adres URL jest inny, więc przeglądarka wykonuje GET dla obrazu zamiast używać wersji z pamięci podręcznej.


2
Działa to dla mnie przez lata, ale dziś mój serwer obrazów (nie kontrolowany przeze mnie) zaczął zwracać uszkodzony link, jeśli nazwa pliku nie jest dokładna. Jeśli ktoś ma inne obejście, byłoby to bardzo mile widziane. Niestety każda odpowiedź w tym wątku jest odmianą tego.
felwithe

@felwithe, może ten serwer szuka rozszerzenia tylko na końcu zapytania? Możesz więc spróbować przetestować to podejście: imagename.jpg?t=1234567&q=.jpglubimagename.jpg#t1234567.jpg
FlameStorm

26

Może to być jeden z dwóch problemów, o których sam wspominasz.

  1. Serwer buforuje obraz
  2. JQuery nie uruchamia się lub przynajmniej nie aktualizuje atrybutu

Szczerze mówiąc, myślę, że to numer dwa. Byłoby o wiele łatwiej, gdybyśmy mogli zobaczyć więcej jQuery. Ale na początek spróbuj najpierw usunąć atrybut, a następnie ustaw go ponownie. Aby zobaczyć, czy to pomaga:

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

Nawet jeśli to działa, opublikuj kod, ponieważ nie jest to optymalne, imo :-)


@Kordonme, czy to tutaj ktoś komentuje „złe” jQuery? (Żartuję, żartuję);)
jay

@Kordonme, tak naprawdę odbywa się to w module obsługi zdarzeń i w tej chwili jest to jedyny wiersz kodu. Dodałem alert tuż przed tym wierszem, aby sprawdzić, czy zdarzenie faktycznie się uruchamia. Zdarzenie jest uruchamiane bez błędów.
Alexis Abril

3
Mam naprawdę wybredną kamerę internetową, która wydaje się zabraniać wszelkich próśb o obrazy statyczne zawierające parametry. Ugh. To świetne rozwiązanie dla mojego wyjątkowego przypadku. Dzięki.
dangowans

To najlepsza odpowiedź, jeśli nie chcesz / potrzebujesz parametrów rezydualnych
RafaSashi,

Dzięki temu pomogłem (buforowałem to tylko dla mnie w Chrome)
Daniel Resch,

14

z jednym wierszem bez obawy o zakodowanie na stałe obrazu src w javascript (dzięki jeerose za pomysły:

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

13
Bądź ostrożny, ponieważ spowoduje to nieskończone dodawanie coraz większej liczby znaków na końcu adresu URL
Alfo

9

Aby ominąć buforowanie i uniknąć dodawania nieskończonych znaczników czasu do adresu URL obrazu, usuń poprzedni znacznik czasu przed dodaniem nowego, oto jak to zrobiłem.

//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

To działa świetnie! jednak jeśli przeładujesz src wiele razy, znacznik czasu zostanie również połączony z adresem URL. Zmodyfikowałem zaakceptowaną odpowiedź, aby sobie z tym poradzić.

$('#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

Czy próbowałeś zresetować html kontenerów obrazów. Oczywiście, jeśli buforuje to przeglądarka, to nie pomogłoby.

function imageUploadComplete () {
    $("#image_container").html("<img src='" + newImageUrl + "'>");
}

2

Czasami rozwiązanie takie jak -

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

też nie odświeżam src poprawnie, wypróbuj to, to zadziałało dla mnie ->

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

1

Przydatne może być użycie „#” jako separatora

Moje obrazy są przechowywane w „ukrytym” folderze powyżej „www”, aby tylko zalogowani użytkownicy mieli do nich dostęp. Z tego powodu nie mogę użyć zwykłego, <img src=/somefolder/1023.jpg>ale wysyłam żądania do serwera w podobny sposób, <img src=?1023>a on odpowiada, wysyłając z powrotem obraz o nazwie „1023”.

Aplikacja służy do kadrowania obrazu, więc po żądaniu ajax do przycięcia obrazu, zostaje zmieniona jako zawartość na serwerze, ale zachowuje swoją oryginalną nazwę. Aby zobaczyć wynik przycinania, po zakończeniu żądania ajax, pierwszy obraz jest usuwany z DOM i wstawiany jest nowy obraz o tej samej nazwie <img src=?1023>.

Aby uniknąć wypłaty gotówki, dodaję do żądania tag „time” poprzedzony „#”, aby stał się podobny <img src=?1023#1467294764124>. Serwer automatycznie odfiltrowuje część skrótu żądania i odpowiada poprawnie, wysyłając z powrotem mój obraz zachowany jako „1023”. Dlatego zawsze otrzymuję ostatnią wersję obrazu bez większego dekodowania po stronie serwera.


1
Po co męczyć się z tym, aby pokazać obraz? Wygląda na bezsensowny kłopot
lucasreta,

0

Być może będę musiał ponownie załadować źródło obrazu kilka razy. Znalazłem rozwiązanie z Lodash, które działa dobrze dla mnie:

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

Istniejący znacznik czasu zostanie obcięty i zastąpiony nowym.


-1

Na podstawie odpowiedzi @kasper Taeymans.

Jeśli po prostu potrzebujesz przeładować obraz (nie zastępuj jego pliku src nowym smth), spróbuj:

$(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>


-2

Po prostu robię to w html:

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

I ponownie załaduj obraz w kodzie z tyłu w następujący sposób:

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

}


1
Ponowne ładowanie strony i ustawienie w asp.NET WebForms tak naprawdę nie jest na ten temat.
Jonas Stensved
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.