So laden Sie ein Element (Bild) in jQuery neu / aktualisieren es

262

Ist es möglich, mit jQuery ein Bild mit einem identischen Dateinamen von einem Server neu zu laden?

Ich habe beispielsweise ein Bild auf einer Seite. Das physische Bild kann sich jedoch aufgrund von Benutzeraktionen ändern. Beachten Sie, dass dies nicht bedeutet, dass sich der Dateiname ändert, sondern die eigentliche Datei.

dh:

  • Der Benutzer zeigt das Bild auf der Standardseite an
  • Benutzer lädt neues Bild hoch
  • Das Standardbild auf der Seite ändert sich nicht (ich gehe davon aus, dass der Dateiname identisch ist und der Browser die zwischengespeicherte Version verwendet).

Unabhängig davon, wie oft der folgende Code aufgerufen wird, bleibt das gleiche Problem bestehen.

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

In der jQuery-Dokumentation wäre die Funktion "Laden" perfekt, wenn sie eine Standardmethode zum Auslösen des Ereignisses hätte, anstatt eine Rückruffunktion an ein erfolgreiches / vollständiges Laden eines Elements zu binden.

Jede Unterstützung wird sehr geschätzt.

Alexis Abril
quelle
1
@Alexis, ist Ihr Problem, dass das Bild im Browser zwischengespeichert wird und nicht aktualisiert wird, nachdem es auf dem Server geändert wurde?
Jay
1
@jeerose, ich glaube, dies ist das Problem, da sich die Datei tatsächlich ändert (gleicher Dateiname) und auf der Seite angezeigt wird, wenn Sie eine vollständige Seitenaktualisierung durchführen.
Alexis Abril

Antworten:

551

Es hört sich so an, als ob Ihr Browser das Bild zwischenspeichert (was ich jetzt bemerke, dass Sie in Ihrer Frage geschrieben haben). Sie können den Browser zwingen, das Bild neu zu laden, indem Sie eine zusätzliche Variable wie folgt übergeben:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
Jay
quelle
1
Das Hinzufügen einer Abfragezeichenfolgenvariablen ist mir völlig durch den Kopf gegangen. Dies löste es und das Bild wird jetzt auf Anfrage neu geladen.
Alexis Abril
45
Gangsta Tipp, liebe es
Dave Jellison
4
Es funktioniert und es ist eine nette Problemumgehung, aber immer noch eine Problemumgehung! Gibt es keine andere Möglichkeit, das Bild abzurufen und dem Browser zu sagen, dass er das zwischengespeicherte Bild vergessen soll?
Spuas
Ich habe eine wirklich wählerische Webcam, die Anfragen nach statischen Bildern, die Parameter enthalten, zu verbieten scheint. Pfui. Ansonsten ist dies eine großartige Lösung.
Dangowans
3
@TomasGonzalez B / c Es besteht die Möglichkeit einer Kollision mit randomund sollte es nie sein, es Datesei denn, Sie sind wirklich sehr, sehr schnell. ; ^) Das Abrufen eines Datums auf dem Client ist nicht so ressourcenintensiv, und Sie können so viele Bilder wiederverwenden, wie Sie gleichzeitig abrufen müssen. Fahren Sie daher mit Schritt 4 fort.
Ruffin
57

Es ist wahrscheinlich nicht der beste Weg, aber ich habe dieses Problem in der Vergangenheit gelöst, indem ich einfach einen Zeitstempel mit JavaScript an die Bild-URL angehängt habe:

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

Beim nächsten Laden wird der Zeitstempel auf die aktuelle Zeit gesetzt und die URL ist unterschiedlich, sodass der Browser ein GET für das Bild ausführt, anstatt die zwischengespeicherte Version zu verwenden.

Kaleb Brasee
quelle
2
Das hat jahrelang für mich funktioniert, aber heute hat mein Image-Server (nicht von mir kontrolliert) einen defekten Link zurückgegeben, wenn der Dateiname nicht genau ist. Wenn jemand eine andere Problemumgehung hat, wäre dies sehr dankbar. Leider ist jede Antwort in diesem Thread eine Variation dieser.
Felwithe
@felwithe, sucht dieser Server möglicherweise nur nach einer Erweiterung am Ende der Abfrage? Sie können also versuchen, diesen Ansatz zu testen: imagename.jpg?t=1234567&q=.jpgoderimagename.jpg#t1234567.jpg
FlameStorm
26

Dies könnte eines der beiden Probleme sein, die Sie selbst erwähnen.

  1. Der Server speichert das Image zwischen
  2. Die jQuery wird nicht ausgelöst oder aktualisiert das Attribut zumindest nicht

Um ehrlich zu sein, denke ich, dass es die Nummer zwei ist. Wäre viel einfacher, wenn wir mehr jQuery sehen könnten. Versuchen Sie jedoch zunächst, das Attribut zu entfernen und dann erneut festzulegen. Nur um zu sehen, ob das hilft:

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

Auch wenn dies funktioniert, poste etwas Code, da dies nicht optimal ist, imo :-)

Kordonme
quelle
@Kordonme, kommentiert hier jemand "schlechtes" jQuery? (Ich scherze, ich
Jay
@Kordonme, dies wird tatsächlich in einem Event-Handler gespeichert und ist im Moment die einzige Codezeile. Ich habe kurz vor dieser Zeile eine Warnung hinzugefügt, um zu überprüfen, ob das Ereignis tatsächlich ausgelöst wird. Das Ereignis wird ohne Fehler ausgelöst.
Alexis Abril
3
Ich habe eine wirklich wählerische Webcam, die Anfragen nach statischen Bildern, die Parameter enthalten, zu verbieten scheint. Pfui. Dies ist eine großartige Lösung für meinen einzigartigen Fall. Vielen Dank.
Dangowans
Dies ist die beste Antwort, wenn Sie keine
Restparameter
Danke das hat geholfen (es hat es nur für mich in Chrome zwischengespeichert)
Daniel Resch
14

mit einer Zeile ohne Sorgen um die Hardcodierung des Bild-src in das Javascript (danke an jeerose für die Ideen:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
Radu
quelle
13
Seien Sie nur vorsichtig, da dadurch unendlich mehr Zeichen am Ende der URL
hinzugefügt werden
9

Um das Caching zu umgehen und das Hinzufügen von unendlichen Zeitstempeln zur Bild-URL zu vermeiden, entfernen Sie den vorherigen Zeitstempel, bevor Sie einen neuen hinzufügen. So habe ich es gemacht.

//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);
}
trennen
quelle
6

Das funktioniert super! Wenn Sie den src jedoch mehrmals neu laden, wird der Zeitstempel auch mit der URL verknüpft. Ich habe die akzeptierte Antwort geändert, um damit umzugehen.

$('#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());
});
Kasper Taeymans
quelle
3

Haben Sie versucht, die HTML-Bildcontainer zurückzusetzen? Wenn der Browser zwischenspeichert, hilft dies natürlich nicht.

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

Manchmal tatsächlich Lösung wie -

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

auch src nicht richtig aktualisieren, probier das aus, es hat bei mir funktioniert ->

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

Die Verwendung von "#" als Trennzeichen kann hilfreich sein

Meine Bilder werden in einem "versteckten" Ordner über "www" gespeichert, sodass nur angemeldete Benutzer Zugriff auf sie haben. Aus diesem Grund kann ich das normale nicht verwenden, <img src=/somefolder/1023.jpg>aber ich sende Anfragen wie an den Server <img src=?1023>und es antwortet, indem es das unter dem Namen '1023' gespeicherte Bild zurücksendet.

Die Anwendung wird zum Zuschneiden von Bildern verwendet. Nach einer Ajax-Anforderung zum Zuschneiden des Bildes wird es als Inhalt auf dem Server geändert, behält jedoch seinen ursprünglichen Namen bei. Um das Ergebnis des Zuschneidens anzuzeigen, wird nach Abschluss der Ajax-Anforderung das erste Bild aus dem DOM entfernt und ein neues Bild mit demselben Namen eingefügt <img src=?1023>.

Um ein Einlösen zu vermeiden, füge ich der Anfrage das "time" -Tag hinzu, dem "#" vorangestellt ist, damit es so wird <img src=?1023#1467294764124>. Der Server filtert automatisch den Hash-Teil der Anfrage heraus und antwortet korrekt, indem er mein als '1023' gespeichertes Bild zurücksendet. Somit bekomme ich immer die letzte Version des Bildes ohne viel serverseitige Dekodierung.

user3506298
quelle
1
Warum all diese Mühen auf sich nehmen, um einem Bild zu dienen? Scheint wie ein sinnloser Ärger
Lucasreta
0

Möglicherweise muss ich die Bildquelle mehrmals neu laden. Ich habe mit Lodash eine Lösung gefunden , die für mich gut funktioniert:

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

Ein vorhandener Zeitstempel wird abgeschnitten und durch einen neuen ersetzt.

slp
quelle
-1

Basierend auf der Antwort von @kasper Taeymans.

Wenn Sie einfach ein neues Image benötigen (ersetzen Sie es nicht durch smth new), versuchen Sie Folgendes:

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

Ich mache das einfach in HTML:

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

Und laden Sie das Bild im Code dahinter wie folgt neu:

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

}}

FTheGodfather
quelle
1
Das Neuladen der Seite und das Einstellen in asp.NET WebForms ist hier nicht wirklich ein Thema.
Jonas Stensved