Come ricaricare / aggiornare un elemento (immagine) in jQuery


262

È possibile ricaricare un'immagine con un nome file identico da un server utilizzando jQuery?

Ad esempio, ho un'immagine su una pagina, tuttavia, l'immagine fisica può cambiare in base alle azioni dell'utente. Nota, questo non significa che il nome del file cambi, ma il file stesso.

vale a dire:

  • L'utente visualizza l'immagine sulla pagina predefinita
  • L'utente carica una nuova immagine
  • L'immagine predefinita nella pagina non cambia (suppongo che ciò sia dovuto al fatto che il nome del file è identico, il browser utilizza la versione memorizzata nella cache)

Indipendentemente dalla frequenza con cui viene chiamato il codice seguente, lo stesso problema persiste.

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

Nella documentazione di jQuery, la funzione "load" sarebbe perfetta se avesse un metodo predefinito di attivazione dell'evento invece di associare una funzione di callback a un carico completo / riuscito di un elemento.

Qualsiasi assistenza è molto apprezzata.


1
@Alexis, il tuo problema è che l'immagine è memorizzata nella cache del browser e non si aggiorna dopo che è stata modificata sul server?
jay

1
@jeerose, credo che questo sia il problema poiché il file cambia (stesso nome file) e si riflette sulla pagina se si esegue un aggiornamento completo della pagina.
Alexis Abril,

Risposte:


551

Sembra che il tuo browser memorizzi nella cache l'immagine (che ora noto che hai scritto nella tua domanda). Puoi forzare il browser a ricaricare l'immagine passando una variabile extra in questo modo:

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

1
L'aggiunta di una variabile della stringa di query mi è passata per la testa. Ciò ha risolto il problema e l'immagine ora viene ricaricata su richiesta.
Alexis Abril,

45
gangsta tip, love it
Dave Jellison,

4
Funziona ed è una bella soluzione, ma comunque una soluzione! Non esiste un modo diverso di recuperare l'immagine dicendo al browser di dimenticare quella memorizzata nella cache?
spuas

Ho una webcam davvero schizzinosa che sembra proibire qualsiasi richiesta di immagini statiche che contengano parametri. Ugh. Questa è un'ottima soluzione altrimenti.
dangowans,

3
@TomasGonzalez B / c c'è una probabilità di ottenere una collisione con random, e non deve mai essere con Datemeno che non siate davvero veloce. ; ^) Ottenere una data sul client non richiede molte risorse e potresti riutilizzare tutte le immagini che devi estrarre in una volta, quindi vai al passaggio 4. Profitto.
Ruffin,

57

Probabilmente non è il modo migliore, ma in passato ho risolto questo problema semplicemente aggiungendo un timestamp all'URL dell'immagine usando JavaScript:

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

Al successivo caricamento, il timestamp viene impostato sull'ora corrente e l'URL è diverso, quindi il browser esegue un GET per l'immagine anziché utilizzare la versione memorizzata nella cache.


2
Questo ha funzionato per me per anni, ma oggi il mio server di immagini (non controllato da me) ha iniziato a restituire un collegamento interrotto se il nome del file non è esatto. Se qualcuno ha un'altra soluzione sarebbe molto apprezzato. Sfortunatamente ogni risposta in questa discussione è una variazione su questa.
felwithe il

@felwithe, potrebbe essere questo server cerca solo l'estensione alla fine della query? Quindi puoi provare a provare questo approccio: imagename.jpg?t=1234567&q=.jpgoppureimagename.jpg#t1234567.jpg
FlameStorm

26

Questo potrebbe essere uno dei due problemi che menzioni te stesso.

  1. Il server memorizza nella cache l'immagine
  2. JQuery non si attiva o almeno non aggiorna l'attributo

Ad essere sincero, penso che sia il numero due. Sarebbe molto più semplice se potessimo vedere un po 'più di jQuery. Ma per cominciare, prova a rimuovere prima l'attributo, quindi impostalo di nuovo. Solo per vedere se questo aiuta:

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

Anche se funziona, pubblica un po 'di codice poiché non è ottimale, imo :-)


@Kordonme, è qui che qualcuno commenta "cattivo" jQuery? (Sto scherzando, sto scherzando);)
jay

@Kordonme, questo è effettivamente contenuto in un gestore di eventi e al momento è l'unica riga di codice. Ho aggiunto un avviso appena prima di questa riga solo per verificare che l'evento si stia effettivamente attivando. L'evento si attiva senza errori.
Alexis Abril,

3
Ho una webcam davvero schizzinosa che sembra proibire qualsiasi richiesta di immagini statiche che contengano parametri. Ugh. Questa è un'ottima soluzione per il mio caso unico. Grazie.
dangowans,

Questa è la risposta migliore se non vuoi / hai bisogno di parametri residui
RafaSashi,

Grazie, questo mi ha aiutato (è stato memorizzato nella cache solo per me in Chrome)
Daniel Resch,

14

con una riga senza preoccupazioni per hardcoding dell'immagine src nel javascript (grazie a jeerose per le idee:

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

13
Fai solo attenzione perché questo aggiungerà infinitamente sempre più caratteri alla fine dell'URL
Alfo

9

Per evitare la memorizzazione nella cache ed evitare di aggiungere infiniti timestamp all'URL dell'immagine, rimuovere il timestamp precedente prima di aggiungerne uno nuovo, ecco come l'ho fatto.

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

Funziona benissimo! tuttavia, se si ricarica l'SCR più volte, anche il timestamp viene concatenato all'URL. Ho modificato la risposta accettata per affrontarla.

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

Hai provato a ripristinare i contenitori di immagini HTML. Ovviamente se è il browser a memorizzare nella cache, questo non sarebbe d'aiuto.

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

2

Alcune volte in realtà soluzione come -

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

anche non aggiornare correttamente src, prova questo, ha funzionato per me ->

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

1

L'uso di "#" come delimitatore potrebbe essere utile

Le mie immagini sono conservate in una cartella "nascosta" sopra "www" in modo che solo gli utenti registrati possano accedervi. Per questo motivo non posso usare l'ordinario <img src=/somefolder/1023.jpg>ma invio richieste simili al server <img src=?1023>e risponde inviando indietro l'immagine conservata con il nome "1023".

L'applicazione viene utilizzata per il ritaglio dell'immagine, quindi dopo una richiesta Ajax per ritagliare l'immagine, viene modificata come contenuto sul server ma mantiene il suo nome originale. Per vedere il risultato del ritaglio, dopo che la richiesta Ajax è stata completata, la prima immagine viene rimossa dal DOM e viene inserita una nuova immagine con lo stesso nome <img src=?1023>.

Per evitare incassi aggiungo alla richiesta il tag "time" anteposto con "#" in modo che diventi simile <img src=?1023#1467294764124>. Il server filtra automaticamente la parte hash della richiesta e risponde correttamente rinviando la mia immagine mantenuta come '1023'. Quindi ottengo sempre l'ultima versione dell'immagine senza molta decodifica lato server.


1
Perché affrontare tutti questi problemi per servire un'immagine? Sembra una seccatura inutile
lucasreta,

0

Potrei dover ricaricare più volte la fonte dell'immagine. Ho trovato una soluzione con Lodash che funziona bene per me:

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

Un timestamp esistente verrà troncato e sostituito con uno nuovo.


-1

Basato sulla risposta di @kasper Taeymans.

Se hai semplicemente bisogno di ricaricare l'immagine (non sostituirla con src con smth new), prova:

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

Lo faccio semplicemente in html:

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

E ricaricare l'immagine in codice dietro in questo modo:

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

}


1
Il ricaricamento della pagina e l'impostazione in asp.NET WebForms non è proprio sull'argomento qui.
Jonas Stensved,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.