it-swarm.com.de

Aktualisieren Sie das Bild mit einer neuen unter derselben URL

Ich greife auf einen Link auf meiner Website zu, der bei jedem Zugriff ein neues Bild liefert.

Mein Problem ist, dass sich das Bild nicht ändert, wenn ich versuche, das Bild in den Hintergrund zu laden und es dann auf der Seite zu aktualisieren. Dies wird jedoch beim Aktualisieren der Seite aktualisiert.

var newImage = new Image();
newImage.src = "http://localhost/image.jpg";

function updateImage()
{
if(newImage.complete) {
    document.getElementById("theText").src = newImage.src;
    newImage = new Image();
    number++;
    newImage.src = "http://localhost/image/id/image.jpg?time=" + new Date();
}

    setTimeout(updateImage, 1000);
}

Header, wie FireFox sie sieht:

HTTP/1.x 200 OK
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Server: Microsoft-HTTPAPI/1.0
Date: Thu, 02 Jul 2009 23:06:04 GMT

Ich muss nur das Bild auf der Seite aktualisieren. Irgendwelche Ideen?

284
QueueHammer

Was ich am Ende tat, war, dass der Server jede Anforderung für ein Image in diesem Verzeichnis der Quelle zuordnet, die ich zu aktualisieren versuchte. Ich ließ meinen Timer dann eine Zahl an das Ende des Namens anhängen, damit das DOM es als neues Bild sehen und laden würde.

Z.B.

http://localhost/image.jpg
//and
http://localhost/image01.jpg

fordert den gleichen Code zur Bilderzeugung an, sieht jedoch anders aus als der Browser.

var newImage = new Image();
newImage.src = "http://localhost/image.jpg";
var count = 0;
function updateImage()
{
    if(newImage.complete) {
        document.getElementById("theText").src = newImage.src;
        newImage = new Image();
        newImage.src = "http://localhost/image/id/image" + count++ + ".jpg";
    }
    setTimeout(updateImage, 1000);
}
2
QueueHammer

Fügen Sie am Ende der URL einen Cache-Unterbrecher hinzu:

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

Dadurch wird der aktuelle Zeitstempel automatisch angehängt, wenn Sie das Bild erstellen, und der Browser wird erneut nach dem Bild suchen, anstatt das im Cache befindliche abzurufen.

304

Ich habe eine Menge Variationen in den Antworten gesehen, um dies zu tun. Deshalb dachte ich, ich würde sie hier zusammenfassen (und eine vierte Methode meiner eigenen Erfindung hinzufügen):


(1) Fügen Sie der URL einen eindeutigen Cache-Busting-Abfrageparameter hinzu, z.

newImage.src = "image.jpg?t=" + new Date().getTime();

Profis: 100% zuverlässig, schnell und einfach zu verstehen und zu implementieren.

Nachteile: Umgeht das Zwischenspeichern insgesamt und bedeutet unnötige Verzögerungen und Bandbreitennutzung, wenn das Bild nicht zwischen den Ansichten wechselt. Füllt möglicherweise den Browser-Cache (und alle Zwischen-Caches) mit vielen, vielen Kopien genau des gleichen Bildes! Erfordert auch das Ändern der Bild-URL.

Verwendungszweck: Wird verwendet, wenn sich das Bild ständig ändert, z. B. für einen Live-Webcam-Feed. Wenn Sie diese Methode verwenden, stellen Sie sicher, dass die Bilder selbst mit Cache-control: no-cache HTTP-Headern bereitgestellt werden !!! (Dies kann häufig mithilfe einer .htaccess-Datei eingerichtet werden). Andernfalls füllen Sie die Caches nach und nach mit alten Versionen des Bildes!


(2) Fügen Sie der URL einen Abfrageparameter hinzu, der sich nur ändert, wenn die Datei dies tut, z.

echo '<img src="image.jpg?m=' . filemtime('image.jpg') . '">';

(Das ist PHP serverseitiger Code, aber der wichtige Punkt hier ist nur, dass ein? M = [letzte Dateiänderung] Querystring an den angehängt wird Dateiname).

Vorteile: 100% zuverlässig, schnell und einfach zu verstehen und zu implementieren, und bewahrt die Caching-Vorteile perfekt.

Nachteile: Erfordert das Ändern der Bild-URL. Auch ein bisschen mehr Arbeit für den Server - er muss Zugriff auf die Datei bekommen, die zuletzt geändert wurde. Erfordert außerdem serverseitige Informationen und ist daher nicht für eine rein clientseitige Lösung zum Überprüfen eines aktualisierten Abbilds geeignet.

Verwendungszweck: Wenn Sie Bilder zwischenspeichern möchten, diese aber möglicherweise am Serverende von Zeit zu Zeit aktualisieren müssen, ohne den Dateinamen selbst zu ändern. UND wenn Sie auf einfache Weise sicherstellen können, dass jeder Bildinstanz in Ihrem HTML-Code der richtige Querystring hinzugefügt wird.


(3) Servieren Sie Ihre Bilder mit der Überschrift Cache-control: max-age=0, must-revalidate Und fügen Sie der URL eine eindeutige memcache - Busting-Fragment-ID hinzu, z.

newImage.src = "image.jpg#" + new Date().getTime();

Die Idee dabei ist, dass der Cache-Control-Header Bilder in den Browser-Cache stellt, diese jedoch sofort als veraltet markiert, sodass der Browser bei jeder erneuten Anzeige beim Server nachfragen muss, ob sie sich geändert haben. Dies stellt sicher, dass der HTTP-Cache des Browsers immer die neueste Kopie des Bildes zurückgibt. Browser verwenden jedoch häufig eine speicherinterne Kopie eines Bildes, falls vorhanden, und überprüfen in diesem Fall nicht einmal ihren HTTP-Cache. Um dies zu verhindern, wird eine Fragmentkennung verwendet: Der Vergleich der speicherinternen Abbilder src enthält die Fragmentkennung, wird jedoch entfernt, bevor der HTTP-Cache abgefragt wird. (So ​​könnten z. B. image.jpg#A Und image.jpg#B Beide aus dem Eintrag image.jpg Im HTTP-Cache des Browsers angezeigt werden, aber image.jpg#B Würde niemals mit in angezeigt -Speicherung der Bilddaten ab dem Zeitpunkt, an dem image.jpg#A zuletzt angezeigt wurde).

Pros: Verwendet die HTTP-Caching-Mechanismen ordnungsgemäß und verwendet zwischengespeicherte Bilder, wenn sie sich nicht geändert haben. Funktioniert für Server, die an einer Abfragezeichenfolge ersticken, die zu einer statischen Image-URL hinzugefügt wurde (da Server keine Fragment-IDs sehen - sie sind nur für den eigenen Gebrauch des Browsers bestimmt).

Cons: Beruht auf etwas zweifelhaftem (oder zumindest schlecht dokumentiertem) Verhalten von Browsern in Bezug auf Bilder mit Fragment-IDs in ihren URLs (Ich habe dies jedoch erfolgreich in FF27, Chrome33 und IE11 getestet ). Sendet weiterhin für jede Bildansicht eine Verlängerungsanforderung an den Server. Dies ist möglicherweise zu viel, wenn sich die Bilder nur selten ändern und/oder die Latenz ein großes Problem darstellt (da Sie auf die Verlängerungsantwort warten müssen, auch wenn das zwischengespeicherte Bild noch in Ordnung ist). . Erfordert das Ändern von Bild-URLs.

Verwendungstermin: Verwenden Sie diese Option, wenn sich Bilder häufig ändern oder vom Client zeitweise aktualisiert werden müssen, ohne dass ein serverseitiges Skript erforderlich ist, Sie jedoch den Vorteil der Zwischenspeicherung wünschen. Beispiel: Abfrage einer Live-Webcam, bei der ein Bild alle paar Minuten unregelmäßig aktualisiert wird. Alternativ können Sie anstelle von (1) oder (2) verwenden, wenn Ihr Server keine Abfragezeichenfolgen für statische Bild-URLs zulässt.


(4) Aktualisieren Sie ein bestimmtes Bild mit Javascript, indem Sie es zuerst in ein verstecktes <iframe> Laden und dann location.reload(true) auf dem contentWindow des iframes aufrufen.

Die Schritte sind:

  • Laden Sie das zu aktualisierende Bild in einen ausgeblendeten Iframe. Dies ist nur ein Einrichtungsschritt - es kann, falls gewünscht, lange im Voraus die eigentliche Aktualisierung durchgeführt werden. Es spielt keine Rolle, ob das Bild zu diesem Zeitpunkt nicht geladen werden kann!

  • Sobald dies erledigt ist, löschen Sie alle Kopien dieses Bildes auf Ihrer Seite (n) oder an einer beliebigen Stelle in einem beliebigen DOM-Knoten (auch außerhalb der Seite, die in Javascript-Variablen gespeichert sind). Dies ist erforderlich, da der Browser andernfalls möglicherweise das Bild einer veralteten Kopie im Speicher anzeigt (dies gilt insbesondere für IE11): Sie müssen sicherstellen, dass alle im Speicher Kopien gelöscht werden, bevor Sie das HTTP aktualisieren Zwischenspeicher. Wenn anderer Javascript-Code asynchron ausgeführt wird, müssen Sie möglicherweise auch verhindern, dass dieser Code in der Zwischenzeit neue Kopien des zu aktualisierenden Bildes erstellt.

  • Rufen Sie iframe.contentWindow.location.reload(true) auf. Das true erzwingt eine Cache-Umgehung, lädt direkt vom Server und überschreibt die vorhandene zwischengespeicherte Kopie.

  • Sobald es fertig ist re - Laden, stellen Sie die ausgeblendeten Bilder wieder her. Sie sollten jetzt die aktuelle Version vom Server anzeigen!

Bei Images mit derselben Domain können Sie das Image direkt in den Iframe laden. Für domänenübergreifende Bilder müssen Sie stattdessen eine HTML-Seite von Ihrer Domain laden, die das Bild in einem <img> - Tag enthält. Andernfalls wird "Zugriff verweigert" angezeigt. Fehler beim Versuch, iframe.contentWindow.reload(...) aufzurufen.

Profis: Funktioniert genau wie die image.reload () Funktion die du wünsch dir im DOM hattest! Ermöglicht das normale Zwischenspeichern von Bildern (auch mit dem Ablaufdatum in der Zukunft, wenn Sie dies wünschen, um häufige erneute Überprüfungen zu vermeiden). Ermöglicht das Aktualisieren eines bestimmten Bildes, ohne die URLs für dieses Bild auf der aktuellen Seite oder auf anderen Seiten zu ändern, wobei nur clientseitiger Code verwendet wird.

Nachteile: Verlässt sich auf Javascript. Es wird nicht 100% ig garantiert, dass es in jedem Browser einwandfrei funktioniert (ich habe dies jedoch erfolgreich in FF27, Chrome33 und IE11 getestet). Sehr kompliziert im Vergleich zu den anderen Methoden.

Verwendungszweck: Wenn Sie eine Sammlung von im Grunde genommen statischen Bildern haben, die zwischengespeichert werden sollen, diese aber dennoch gelegentlich aktualisieren und sofort visuelles Feedback erhalten müssen, dass die Aktualisierung stattgefunden hat. (Insbesondere, wenn nur das Aktualisieren der gesamten Browser-Seite nicht funktioniert, wie in einigen Web-Apps, die auf AJAX zum Beispiel) aufgebaut sind.) Und wenn die Methoden (1) - (3) nicht durchführbar sind, weil (aus welchem ​​Grund auch immer) Sie können nicht alle URLs ändern, die möglicherweise das zu aktualisierende Bild anzeigen. (Beachten Sie, dass das Bild mit diesen drei Methoden aktualisiert wird, aber wenn eine andere page versucht dann, das Bild anzuzeigen ohne die entsprechende Abfragezeichenfolge oder Fragmentkennung, möglicherweise wird stattdessen eine ältere Version angezeigt).

Die Details der Implementierung auf eine ziemlich robuste und flexible Art und Weise sind unten angegeben:

Angenommen, Ihre Website enthält ein leeres 1x1-Pixel-GIF im URL-Pfad /img/1x1blank.gif Und das folgende einzeilige Skript PHP=) (nur erforderlich, um die erzwungene Aktualisierung auf = anzuwenden domainübergreifend Bilder und können natürlich in jeder serverseitigen Skriptsprache) unter dem URL-Pfad /echoimg.php umgeschrieben werden:

<img src="<?=htmlspecialchars(@$_GET['src'],ENT_COMPAT|ENT_HTML5,'UTF-8')?>">

Dann ist hier eine realistische Implementierung, wie Sie dies alles in Javascript tun können. Es sieht ein bisschen kompliziert aus, aber es gibt viele Kommentare, und die wichtige Funktion ist nur forceImgReload () - die ersten beiden sind leere und nicht leere Bilder. Sie sollten so gestaltet sein, dass sie effizient mit Ihrem eigenen HTML-Code arbeiten funktioniert am besten für Sie; Viele der darin enthaltenen Komplikationen können für Ihre Website unnötig sein:

// This function should blank all images that have a matching src, by changing their src property to /img/1x1blank.gif.
// ##### You should code the actual contents of this function according to your page design, and what images there are on them!!! #####
// Optionally it may return an array (or other collection or data structure) of those images affected.
// This can be used by imgReloadRestore() to restore them later, if that's an efficient way of doing it (otherwise, you don't need to return anything).
// NOTE that the src argument here is just passed on from forceImgReload(), and MAY be a relative URI;
// However, be aware that if you're reading the src property of an <img> DOM object, you'll always get back a fully-qualified URI,
// even if the src attribute was a relative one in the original HTML.  So watch out if trying to compare the two!
// NOTE that if your page design makes it more efficient to obtain (say) an image id or list of ids (of identical images) *first*, and only then get the image src,
// you can pass this id or list data to forceImgReload() along with (or instead of) a src argument: just add an extra or replacement parameter for this information to
// this function, to imgReloadRestore(), to forceImgReload(), and to the anonymous function returned by forceImgReload() (and make it overwrite the earlier parameter variable from forceImgReload() if truthy), as appropriate.
function imgReloadBlank(src)
{
  // ##### Everything here is provisional on the way the pages are designed, and what images they contain; what follows is for example purposes only!
  // ##### For really simple pages containing just a single image that's always the one being refreshed, this function could be as simple as just the one line:
  // ##### document.getElementById("myImage").src = "/img/1x1blank.gif";

  var blankList = [],
      fullSrc = /* Fully qualified (absolute) src - i.e. prepend protocol, server/domain, and path if not present in src */,
      imgs, img, i;

  for each (/* window accessible from this one, i.e. this window, and child frames/iframes, the parent window, anything opened via window.open(), and anything recursively reachable from there */)
  {
    // get list of matching images:
    imgs = theWindow.document.body.getElementsByTagName("img");
    for (i = imgs.length; i--;) if ((img = imgs[i]).src===fullSrc)  // could instead use body.querySelectorAll(), to check both tag name and src attribute, which would probably be more efficient, where supported
    {
      img.src = "/img/1x1blank.gif";  // blank them
      blankList.Push(img);            // optionally, save list of blanked images to make restoring easy later on
    }
  }

  for each (/* img DOM node held only by javascript, for example in any image-caching script */) if (img.src===fullSrc)
  {
    img.src = "/img/1x1blank.gif";   // do the same as for on-page images!
    blankList.Push(img);
  }

  // ##### If necessary, do something here that tells all accessible windows not to create any *new* images with src===fullSrc, until further notice,
  // ##### (or perhaps to create them initially blank instead and add them to blankList).
  // ##### For example, you might have (say) a global object window.top.blankedSrces as a propery of your topmost window, initially set = {}.  Then you could do:
  // #####
  // #####     var bs = window.top.blankedSrces;
  // #####     if (bs.hasOwnProperty(src)) bs[src]++; else bs[src] = 1;
  // #####
  // ##### And before creating a new image using javascript, you'd first ensure that (blankedSrces.hasOwnProperty(src)) was false...
  // ##### Note that incrementing a counter here rather than just setting a flag allows for the possibility that multiple forced-reloads of the same image are underway at once, or are overlapping.

  return blankList;   // optional - only if using blankList for restoring back the blanked images!  This just gets passed in to imgReloadRestore(), it isn't used otherwise.
}




// This function restores all blanked images, that were blanked out by imgReloadBlank(src) for the matching src argument.
// ##### You should code the actual contents of this function according to your page design, and what images there are on them, as well as how/if images are dimensioned, etc!!! #####
function imgReloadRestore(src,blankList,imgDim,loadError);
{
  // ##### Everything here is provisional on the way the pages are designed, and what images they contain; what follows is for example purposes only!
  // ##### For really simple pages containing just a single image that's always the one being refreshed, this function could be as simple as just the one line:
  // ##### document.getElementById("myImage").src = src;

  // ##### if in imgReloadBlank() you did something to tell all accessible windows not to create any *new* images with src===fullSrc until further notice, retract that setting now!
  // ##### For example, if you used the global object window.top.blankedSrces as described there, then you could do:
  // #####
  // #####     var bs = window.top.blankedSrces;
  // #####     if (bs.hasOwnProperty(src)&&--bs[src]) return; else delete bs[src];  // return here means don't restore until ALL forced reloads complete.

  var i, img, width = imgDim&&imgDim[0], height = imgDim&&imgDim[1];
  if (width) width += "px";
  if (height) height += "px";

  if (loadError) {/* If you want, do something about an image that couldn't load, e.g: src = "/img/brokenImg.jpg"; or alert("Couldn't refresh image from server!"); */}

  // If you saved & returned blankList in imgReloadBlank(), you can just use this to restore:

  for (i = blankList.length; i--;)
  {
    (img = blankList[i]).src = src;
    if (width) img.style.width = width;
    if (height) img.style.height = height;
  }
}




// Force an image to be reloaded from the server, bypassing/refreshing the cache.
// due to limitations of the browser API, this actually requires TWO load attempts - an initial load into a hidden iframe, and then a call to iframe.contentWindow.location.reload(true);
// If image is from a different domain (i.e. cross-domain restrictions are in effect, you must set isCrossDomain = true, or the script will crash!
// imgDim is a 2-element array containing the image x and y dimensions, or it may be omitted or null; it can be used to set a new image size at the same time the image is updated, if applicable.
// if "twostage" is true, the first load will occur immediately, and the return value will be a function
// that takes a boolean parameter (true to proceed with the 2nd load (including the blank-and-reload procedure), false to cancel) and an optional updated imgDim.
// This allows you to do the first load early... for example during an upload (to the server) of the image you want to (then) refresh.
function forceImgReload(src, isCrossDomain, imgDim, twostage)
{
  var blankList, step = 0,                                // step: 0 - started initial load, 1 - wait before proceeding (twostage mode only), 2 - started forced reload, 3 - cancelled
      iframe = window.document.createElement("iframe"),   // Hidden iframe, in which to perform the load+reload.
      loadCallback = function(e)                          // Callback function, called after iframe load+reload completes (or fails).
      {                                                   // Will be called TWICE unless twostage-mode process is cancelled. (Once after load, once after reload).
        if (!step)  // initial load just completed.  Note that it doesn't actually matter if this load succeeded or not!
        {
          if (twostage) step = 1;  // wait for twostage-mode proceed or cancel; don't do anything else just yet
          else { step = 2; blankList = imgReloadBlank(src); iframe.contentWindow.location.reload(true); }  // initiate forced-reload
        }
        else if (step===2)   // forced re-load is done
        {
          imgReloadRestore(src,blankList,imgDim,(e||window.event).type==="error");    // last parameter checks whether loadCallback was called from the "load" or the "error" event.
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        }
      }
  iframe.style.display = "none";
  window.parent.document.body.appendChild(iframe);    // NOTE: if this is done AFTER setting src, Firefox MAY fail to fire the load event!
  iframe.addEventListener("load",loadCallback,false);
  iframe.addEventListener("error",loadCallback,false);
  iframe.src = (isCrossDomain ? "/echoimg.php?src="+encodeURIComponent(src) : src);  // If src is cross-domain, script will crash unless we embed the image in a same-domain html page (using server-side script)!!!
  return (twostage
    ? function(proceed,dim)
      {
        if (!twostage) return;
        twostage = false;
        if (proceed)
        {
          imgDim = (dim||imgDim);  // overwrite imgDim passed in to forceImgReload() - just in case you know the correct img dimensions now, but didn't when forceImgReload() was called.
          if (step===1) { step = 2; blankList = imgReloadBlank(src); iframe.contentWindow.location.reload(true); }
        }
        else
        {
          step = 3;
          if (iframe.contentWindow.stop) iframe.contentWindow.stop();
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        }
      }
    : null);
}

Um eine Aktualisierung eines Bilds zu erzwingen, das sich in derselben Domain wie Ihre Seite befindet, können Sie Folgendes tun:

forceImgReload("myimage.jpg");

So aktualisieren Sie ein Bild von einer anderen Stelle (domänenübergreifend):

forceImgReload("http://someother.server.com/someimage.jpg", true);

Eine fortgeschrittenere Anwendung könnte darin bestehen, ein Image nach dem Hochladen einer neuen Version auf Ihren Server neu zu laden und gleichzeitig mit dem Hochladen die erste Phase des Ladevorgangs vorzubereiten, um die sichtbare Verzögerung beim erneuten Laden für den Benutzer zu minimieren. Wenn Sie den Upload über AJAX durchführen und der Server ein sehr einfaches JSON-Array [Erfolg, Breite, Höhe] zurückgibt, sieht Ihr Code möglicherweise folgendermaßen aus:

// fileForm is a reference to the form that has a the <input typ="file"> on it, for uploading.
// serverURL is the url at which the uploaded image will be accessible from, once uploaded.
// The response from uploadImageToServer.php is a JSON array [success, width, height]. (A boolean and two ints).
function uploadAndRefreshCache(fileForm, serverURL)
{
  var xhr = new XMLHttpRequest(),
      proceedWithImageRefresh = forceImgReload(serverURL, false, null, true);
  xhr.addEventListener("load", function(){ var arr = JSON.parse(xhr.responseText); if (!(arr&&arr[0])) { proceedWithImageRefresh(false); doSomethingOnUploadFailure(...); } else { proceedWithImageRefresh(true,[arr[1],ar[2]]); doSomethingOnUploadSuccess(...); }});
  xhr.addEventListener("error", function(){ proceedWithImageRefresh(false); doSomethingOnUploadError(...); });
  xhr.addEventListener("abort", function(){ proceedWithImageRefresh(false); doSomethingOnUploadAborted(...); });
  // add additional event listener(s) to track upload progress for graphical progress bar, etc...
  xhr.open("post","uploadImageToServer.php");
  xhr.send(new FormData(fileForm));
}

Ein letzter Hinweis: Obwohl es sich bei diesem Thema um Bilder handelt, gilt es möglicherweise auch für andere Arten von Dateien oder Ressourcen. Beispiel: Verhindern der Verwendung veralteter Skript- oder CSS-Dateien oder sogar Aktualisieren aktualisierter PDF Dokumente (mit (4) nur, wenn das Öffnen im Browser konfiguriert ist). Methode (4) In diesen Fällen müssen einige Änderungen an dem oben genannten Javascript vorgenommen werden.

197
Doin

Als Alternative zu ...

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

...Es scheint, dass...

newImage.src = "http://localhost/image.jpg#" + new Date().getTime();

... reicht aus, um den Browser-Cache zu täuschen, ohne Upstream-Caches zu umgehen, vorausgesetzt, Sie haben die richtigen Cache-Control-Header zurückgegeben. Sie können zwar verwenden ...

Cache-Control: no-cache, must-revalidate

... Sie verlieren die Vorteile der If-Modified-Since- oder If-None-Match-Header, so etwas wie ...

Cache-Control: max-age=0, must-revalidate

... sollte verhindern, dass der Browser das gesamte Bild erneut lädt, wenn es nicht tatsächlich geändert wurde. Getestet und arbeitet mit IE, Firefox und Chrome. Ärgerlicherweise schlägt es auf Safari fehl, wenn Sie nicht ...

Cache-Control: no-store

... obwohl dies immer noch vorzuziehen ist, um Upstream-Caches mit Hunderten identischer Bilder zu füllen, insbesondere wenn sie auf Ihrem eigenen Server ausgeführt werden. ;-)

Update (2014-09-28): Heutzutage sieht es so aus, als würde Cache-Control: no-store auch für Chrome benötigt.

173
Aya

Entfernen Sie nach dem Erstellen des neuen Images das alte Image aus dem DOM und ersetzen Sie es durch das neue Image.

Sie könnten bei jedem Aufruf von updateImage nach neuen Bildern greifen, diese jedoch nicht zur Seite hinzufügen.

Es gibt verschiedene Möglichkeiten, dies zu tun. So etwas würde funktionieren.

function updateImage()
{
    var image = document.getElementById("theText");
    if(image.complete) {
        var new_image = new Image();
        //set up the new image
        new_image.id = "theText";
        new_image.src = image.src;           
        // insert new image and remove old
        image.parentNode.insertBefore(new_image,image);
        image.parentNode.removeChild(image);
    }

    setTimeout(updateImage, 1000);
}

Wenn das funktioniert, ist es, wenn es immer noch Probleme gibt, wahrscheinlich ein Caching-Problem, über das die anderen Antworten sprechen.

6
BaroqueBobcat

Eine Antwort ist das hackish Hinzufügen einiger Abfrageparameter, wie vorgeschlagen wurde.

Eine bessere Antwort ist die Ausgabe einiger zusätzlicher Optionen in Ihrem HTTP-Header.

Pragma: no-cache
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Cache-Control: no-cache, must-revalidate

Wenn Sie ein Datum in der Vergangenheit angeben, wird es vom Browser nicht zwischengespeichert. Cache-Control wurde in HTTP/1.1 hinzugefügt, und das must-revalidate-Tag gibt an, dass Proxys auch unter erschwerten Umständen niemals ein altes Image bereitstellen sollten, und Pragma: no-cache ist für aktuelle moderne Browser/Caches nicht unbedingt erforderlich, kann jedoch bei einigen alten, knorrigen Fehlern helfen Implementierungen.

4
Edward KMETT

function reloadImage(imageId)
{
   path = '../showImage.php?cache='; //for example
   imageObject = document.getElementById(imageId);
   imageObject.src = path + (new Date()).getTime();
}
<img src='../showImage.php' id='myimage' />

<br/>

<input type='button' onclick="reloadImage('myimage')" />

3
Mahmoud

Verwenden Sie einen wertlosen Querstring, um eine eindeutige URL zu erstellen:

function updateImage()
{
    if(newImage.complete) {
        document.getElementById("theText").src = newImage.src;
        newImage = new Image();
        number++;
        newImage.src = "http://localhost/image.jpg?" + new Date();
    }

    setTimeout(updateImage, 1000);
}
1
Joel

Ich hatte eine Anforderung: 1) Ich kann dem Bild kein ?var=xx Hinzufügen. 2) Es sollte domänenübergreifend funktionieren

Ich mag die Option 4 in diese Antwort mit einer, aber:

  • es hat Probleme, zuverlässig mit Crossdomain zu arbeiten (und es muss der Servercode berührt werden).

Mein schneller und schmutziger Weg ist:

  1. Versteckten Iframe erstellen
  2. Lädt die aktuelle Seite (ja die ganze Seite)
  3. iframe.contentWindow.location.reload(true);
  4. Setzt die Bildquelle auf sich selbst zurück

Hier ist es

function RefreshCachedImage() {
    if (window.self !== window.top) return; //prevent recursion
    var $img = $("#MYIMAGE");
    var src = $img.attr("src");
    var iframe = document.createElement("iframe");
    iframe.style.display = "none";
    window.parent.document.body.appendChild(iframe);
    iframe.src = window.location.href;
    setTimeout(function () {
        iframe.contentWindow.location.reload(true);
        setTimeout(function () {
            $img.removeAttr("src").attr("src", src);
        }, 2000);
    }, 2000);
}

Ja, ich weiß, setTimeout ... Du musst das in richtige Onload-Ereignisse ändern.

1
jazzcat

Der folgende Code ist nützlich, um das Bild zu aktualisieren, wenn auf eine Schaltfläche geklickt wird.

function reloadImage(imageId) {
   imgName = 'vishnu.jpg'; //for example
   imageObject = document.getElementById(imageId);
   imageObject.src = imgName;
}

<img src='vishnu.jpg' id='myimage' />

<input type='button' onclick="reloadImage('myimage')" />
1
Codemaker
document.getElementById("img-id").src = document.getElementById("img-id").src

setze seine eigene src als src.

1
Hardik

Ich habe dieses Problem gelöst, indem ich die Daten über ein Servlet zurücksende.

response.setContentType("image/png");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setDateHeader("Expires", 0);

BufferedImage img = ImageIO.read(new File(imageFileName));

ImageIO.write(img, "png", response.getOutputStream());

Dann geben Sie von der Seite einfach das Servlet mit einigen Parametern, um die korrekte Bilddatei zu erhalten.

<img src="YourServlet?imageFileName=imageNum1">
0
tinymothbrain
<img src='someurl.com/someimage.ext' onload='imageRefresh(this, 1000);'>

Dann weiter unten in etwas Javascript

<script language='javascript'>
 function imageRefresh(img, timeout) {
    setTimeout(function() {
     var d = new Date;
     var http = img.src;
     if (http.indexOf("&d=") != -1) { http = http.split("&d=")[0]; } 

     img.src = http + '&d=' + d.getTime();
    }, timeout);
  }
</script>

Das heißt, wenn das Image geladen wird, wird das Laden in 1 Sekunde geplant. Ich verwende dies auf einer Seite mit Home Security-Kameras unterschiedlichen Typs.

0
J Fields

Das folgende Beispiel basiert stark auf Doin # 4-Code und vereinfacht die Verwendung von document.write anstelle von src in der iframe zur Unterstützung von CORS. Außerdem wird nur der Browser-Cache aufgehoben und nicht jedes Bild auf der Seite neu geladen.

Unten ist in TypeScript geschrieben und verwendet die Bibliothek angular$ q promise, nur fyi, sollte aber leicht genug sein, um auf Vanilla Javascript portieren zu können. Die Methode soll innerhalb einer TypeScript-Klasse leben. 

Gibt ein Versprechen zurück, das aufgelöst wird, wenn der iframe vollständig neu geladen wurde. Nicht intensiv getestet, funktioniert aber gut für uns.

    mmForceImgReload(src: string): ng.IPromise<void> {
        var deferred = $q.defer<void>();
        var iframe = window.document.createElement("iframe");

        var firstLoad = true;
        var loadCallback = (e) => {
            if (firstLoad) {
                firstLoad = false;
                iframe.contentWindow.location.reload(true);
            } else {
                if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
                deferred.resolve();
            }
        }
        iframe.style.display = "none";
        window.parent.document.body.appendChild(iframe);
        iframe.addEventListener("load", loadCallback, false);
        iframe.addEventListener("error", loadCallback, false);
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write('<html><head><title></title></head><body><img src="' + src + '"></body></html>');
        doc.close();
        return deferred.promise;
    }
0
Victor

Hier ist meine Lösung. Es ist sehr einfach. Die Rahmenplanung könnte besser sein.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">      
        <title>Image Refresh</title>
    </head>

    <body>

    <!-- Get the initial image. -->
    <img id="frame" src="frame.jpg">

    <script>        
        // Use an off-screen image to load the next frame.
        var img = new Image();

        // When it is loaded...
        img.addEventListener("load", function() {

            // Set the on-screen image to the same source. This should be instant because
            // it is already loaded.
            document.getElementById("frame").src = img.src;

            // Schedule loading the next frame.
            setTimeout(function() {
                img.src = "frame.jpg?" + (new Date).getTime();
            }, 1000/15); // 15 FPS (more or less)
        })

        // Start the loading process.
        img.src = "frame.jpg?" + (new Date).getTime();
    </script>
    </body>
</html>
0
Timmmm