Actualizar imagen con una nueva en la misma url


Estoy accediendo a un enlace en mi sitio que proporcionará una nueva imagen cada vez que se acceda.

El problema con el que me estoy topando es que si intento cargar la imagen en el fondo y luego actualizar la de la página, la imagen no cambia though aunque se actualiza cuando vuelvo a cargar la página.

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);
}

Encabezados como FireFox los ve:

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

Necesito forzar una actualización de solo esa imagen en la página. Alguna idea?

Author: AlexMA, 2009-07-03

16 answers

Intenta agregar un cachebreaker al final de la url:

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

Esto agregará la marca de tiempo actual automáticamente cuando esté creando la imagen, y hará que el navegador vuelva a buscar la imagen en lugar de recuperar la que está en la caché.

 288
Author: Paolo Bergantino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 22:46:10

He visto muchas variaciones en las respuestas sobre cómo hacer esto, así que pensé en resumirlas aquí (además de agregar un 4to método de mi propia invención):


(1) Agregue un parámetro de consulta único que revienta caché a la URL, como:

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

Pros: 100% confiable, rápido y fácil de entender e implementar.

Contras: Evita el almacenamiento en caché por completo, lo que significa retrasos innecesarios y uso de ancho de banda cuando la imagen no cambia entre vista. Potencialmente llenará la caché del navegador (y cualquier caché intermedia) con muchas, muchas copias de exactamente la misma imagen! Además, requiere modificar la URL de la imagen.

Cuándo usar: Usar cuando la imagen está en constante cambio, como para una transmisión de cámara web en vivo. Si utiliza este método, asegúrese de servir las propias imágenes con Cache-control: no-cache encabezados HTTP!!! (A menudo esto se puede configurar usando a .archivo htaccess). De lo contrario, irá llenando progresivamente cachés con versiones antiguas de la imagen!


(2) Agregue un parámetro de consulta a la URL que cambia solo cuando el archivo lo hace, por ejemplo:

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

(Eso es código PHP del lado del servidor, pero el punto importante aquí es solo que a ?m = [file last-modified time] querystring se añade al nombre del archivo).

Pros: 100% confiable, rápido y fácil de entender e implementar, y conserva las ventajas del almacenamiento en caché a la perfección.

Contras: Requiere modificar la URL de la imagen. Además, un poco más de trabajo para el servidor - tiene que obtener acceso al archivo-última hora modificada. Además, requiere información del lado del servidor, por lo que no es adecuado para una solución puramente del lado del cliente para verificar una imagen actualizada.

Cuándo usar: Cuando desea almacenar imágenes en caché, pero puede necesitar actualizarlas en el extremo del servidor de vez en cuando sin cambiar el nombre del archivo en sí. Y cuando puede asegurarse fácilmente de que se agrega la cadena de consultas correcta a cada instancia de imagen en su HTML.


(3) Sirva sus imágenes con el encabezado Cache-control: max-age=0, must-revalidate, y agregue un identificador de fragmento único memcache -busting a la URL, como:

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

La idea aquí es que el encabezado cache-control ponga imágenes en la caché del navegador, pero inmediatamente las marque obsoletas, de modo que cada vez que se vuelvan a mostrar el navegador debe verificar con el servidor si han cambiado. Esto asegura que la caché HTTP del navegador siempre devuelve la última copia del imagen. Sin embargo, los navegadores a menudo reutilizan una copia en memoria de una imagen si tienen una, y ni siquiera comprueban su caché HTTP en ese caso. Para evitar esto, se utiliza un identificador de fragmento: La comparación de imágenes en memoria src incluye el identificador de fragmento, pero se elimina antes de consultar la caché HTTP. (Así, por ejemplo, image.jpg#A y image.jpg#B podrían mostrarse desde la entrada image.jpg en la caché HTTP del navegador, pero image.jpg#B nunca se mostraría usando datos de imagen retenidos en memoria desde la última vez que se mostró image.jpg#A).

Pros: Hace un uso adecuado de los mecanismos de caché HTTP, y utiliza imágenes en caché si no han cambiado. Funciona para servidores que se atragantan con una querystring agregada a una URL de imagen estática(ya que los servidores nunca ven identificadores de fragmentos-son solo para uso propio de los navegadores).

Contras: Se basa en un comportamiento un tanto dudoso (o al menos mal documentado) de los navegadores, con respecto a las imágenes con identificadores de fragmentos en sus URL (Sin embargo, he probado esto con éxito en FF27, Chrome33, y IE11). Todavía envía una solicitud de revalidación al servidor para cada vista de imagen, lo que puede ser excesivo si las imágenes solo cambian raramente y/o la latencia es un gran problema (ya que necesita esperar la respuesta de revalidación incluso cuando la imagen almacenada en caché sigue siendo buena). Requiere modificar las URL de las imágenes.

Cuándo usar: Usar cuando las imágenes pueden cambiar con frecuencia, o necesitan ser actualizadas intermitentemente por el cliente sin implicación del script del lado del servidor, pero donde aún desea la ventaja del almacenamiento en caché. Por ejemplo, sondeando una cámara web en vivo que actualiza una imagen de forma irregular cada pocos minutos. Alternativamente, use en lugar de (1) o (2) si su servidor no permite querystrings en URLs de imágenes estáticas.


(4) Actualizar forzosamente una imagen en particular usando Javascript, primero cargándola en un <iframe> oculto y luego llamando a location.reload(true) en el contentWindow del iframe.

Los pasos son:

  • Cargue la imagen que se va a actualizar en un iframe oculto. Esto es solo un paso de configuración-se puede hacer mucho antes de la actualización real, si se desea. Ni siquiera importa si la imagen no se carga en esta etapa!

  • Una vez hecho esto, borre todas las copias de esa imagen en su(s) página (s) o en cualquier lugar de cualquier nodo DOM (incluso los fuera de página almacenados en variables javascript). Esto es necesario porque el navegador puede mostrar la imagen de un copia obsoleta en memoria (IE11 especialmente hace esto): Necesita asegurarse de que todas las copias en memoria estén borradas, antes de actualizar la caché HTTP. Si otro código javascript se está ejecutando de forma asíncrona, es posible que también deba evitar que ese código cree nuevas copias de la imagen que se va a actualizar mientras tanto.

  • Llame iframe.contentWindow.location.reload(true). El true fuerza un bypass de caché, recargando directamente desde el servidor y sobrescribiendo la copia en caché existente.

  • Una vez que es finished re-loading, restore the blanked images. ¡Ahora deberían mostrar la versión nueva del servidor!

Para las imágenes del mismo dominio, puede cargar la imagen en el iframe directamente. Para imágenes entre dominios, debe cargar una página HTML desde su dominio que contenga la imagen en una etiqueta <img>, de lo contrario obtendrá un error de "Acceso denegado" al intentar llamar a iframe.contentWindow.reload(...).

Pros: Funciona igual que la imagen.cargar() function you wish the DOM had! Permite que las imágenes se almacenen en caché normalmente (incluso con fechas de caducidad futuras si las desea, evitando así la revalidación frecuente). Le permite actualizar una imagen en particular sin alterar las URL de esa imagen en la página actual o en cualquier otra página, utilizando solo código del lado del cliente.

Contras: Depende de Javascript. No 100% garantizado para funcionar correctamente en todos los navegadores (he probado esto con éxito en FF27, Chrome33, y IE11 aunque). Muy complicado en relación con los otros métodos.

Cuándo usar: Cuando tiene una colección de imágenes básicamente estáticas que desea almacenar en caché, pero aún necesita poder actualizarlas ocasionalmente y obtener información visual inmediata de que la actualización tuvo lugar. (Especialmente cuando simplemente refrescar toda la página del navegador no funcionaría, como en algunas aplicaciones web construidas en AJAX, por ejemplo). Y cuando los métodos (1)-(3) no son factibles porque (por cualquier razón) no se puede cambia todas las URL que podrían mostrar la imagen que necesitas actualizar. (Tenga en cuenta que usando esos 3 métodos la imagen se actualizará, pero si otra página intenta mostrar esa imagen sin el identificador de consulta o fragmento apropiado, puede mostrar una versión anterior en su lugar).

Los detalles de la implementación de esto de una manera hada robusta y flexible se dan a continuación:

Supongamos que su sitio web contiene un píxel en blanco de 1x1.gif en la ruta URL /img/1x1blank.gif, y también tiene el siguiente script PHP de una línea (solo necesario para aplicar actualización forzada a imágenes cross-domain, y puede reescribirse en cualquier lenguaje de scripting del lado del servidor, por supuesto) en la ruta URL /echoimg.php:

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

Entonces, aquí hay una implementación realista de cómo podría hacer todo esto en Javascript. Parece un poco complicado, pero hay un montón de comentarios, y la función importante es sólo forceImgReload () - los dos primeros sólo en blanco y imágenes no en blanco, y debe ser diseñado para trabajar de manera eficiente con su propio HTML, por lo que el código como funciona mejor para usted; gran parte de las complicaciones en ellos pueden ser innecesarios para su sitio web:

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

Entonces, para forzar una actualización de una imagen ubicada en el mismo dominio que su página, simplemente puede hacer:

forceImgReload("myimage.jpg");

Para actualizar una imagen desde otro lugar (cross-domain):

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

Una aplicación más avanzada podría ser volver a cargar una imagen después de subir una nueva versión a su servidor, preparando la etapa inicial del proceso de recarga simultánea con la carga, para minimizar el retraso de recarga visible para el usuario. Si está haciendo la carga a través de AJAX, y el servidor está devolviendo una matriz JSON muy simple [success, width, height], entonces su código podría verse algo como esto:

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

Una nota final: Aunque este tema es sobre imágenes, potencialmente se aplica a otros tipos de archivos o recursos también. Por ejemplo, evitar el uso de scripts obsoletos o archivos CSS, o tal vez incluso actualizar documentos PDF actualizados (usando (4) solo si está configurado para abrir en el navegador). Method (4) podría requerir algunos cambios en el javascript anterior, en estos casos.

 170
Author: Doin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-04 06:07:12

Como alternativa a...

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

Seems eso parece...

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

Sufficient es suficiente para engañar a la caché del navegador sin pasar por ningún caché de origen, suponiendo que devolvió los encabezados Cache-Control correctos. Aunque se puede utilizar...

Cache-Control: no-cache, must-revalidate

...pierdes los beneficios de los encabezados If-Modified-Since o If-None-Match, así que algo así...

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

...debe evitar que el navegador vuelva a descargar la imagen completa si en realidad no ha cambiado. Probado y trabajando en IE, Firefox, y Chrome. Fastidiosamente falla en Safari a menos que lo use...

Cache-Control: no-store

...aunque esto todavía puede ser preferible a llenar cachés ascendentes con cientos de imágenes idénticas, particularmente cuando se están ejecutando en su propio servidor. ;-)

Actualización (2014-09-28): Hoy en día parece que Cache-Control: no-store es necesario para Chrome también.

 168
Author: Aya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-28 19:10:27

Después de crear la nueva imagen, ¿está eliminando la imagen antigua del DOM y reemplazándola con la nueva?

Podría estar tomando nuevas imágenes cada llamada de updateImage, pero no agregándolas a la página.

Hay varias maneras de hacerlo. Algo como esto funcionaría.

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);
}

Después de que eso funcione, si todavía hay problemas es probablemente un problema de almacenamiento en caché como las otras respuestas hablan.

 6
Author: BaroqueBobcat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 23:44:12

Una respuesta es hackishly añadir algún parámetro de consulta get como se ha sugerido.

Una mejor respuesta es emitir un par de opciones adicionales en su encabezado HTTP.

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

Al proporcionar una fecha en el pasado, el navegador no la almacenará en caché. Cache-Control se agregó en HTTP / 1.1 y la etiqueta must-revalidate indica que los proxies nunca deben mostrar una imagen antigua, incluso bajo circunstancias atenuantes, y el Pragma: no-cache no es realmente necesario para los navegadores/cachés modernos actuales, pero puede ayudar con algunas viejas implementaciones rotas.

 4
Author: Edward KMETT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 22:57:03

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
Author: Mahmoud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-09 20:47:59

Lo que terminé haciendo fue que el servidor mapeara cualquier solicitud de una imagen en ese directorio con la fuente que estaba tratando de actualizar. Entonces tuve mi temporizador de añadir un número al final del nombre para el DOM vería como una nueva imagen y la carga.

Por ejemplo

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

Solicitará el mismo código de generación de imágenes, pero se verá como imágenes diferentes para el navegador.

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
Author: QueueHammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-29 17:48:28

Intenta usar un querystring sin valor para convertirlo en una url única:

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
Author: Joel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 22:46:44
document.getElementById("img-id").src = document.getElementById("img-id").src

Establece su propio src como su src.

 1
Author: Hardik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-23 09:57:26

Tenía un requisito: 1) no puedo agregar ningún ?var=xx a la imagen 2) debería funcionar entre dominios

Realmente me gusta la opción # 4 en esta respuesta con una pero:

  • tiene problemas para trabajar con crossdomain de forma fiable (y requiere tocar el código del servidor).

Mi camino rápido y sucio es:

  1. Crear iframe oculto
  2. Cargar la página actual en ella (sí, todo el page)
  3. iframe.contentWindow.location.reload(true);
  4. Vuelva a establecer la fuente de la imagen a sí misma

Aquí está

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);
}

Sí, lo sé, setTimeout... Tienes que cambiar eso a eventos onload adecuados.

 1
Author: jazzcat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:24

Resolví este problema enviando los datos de vuelta a través de un servlet.

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());

A continuación, desde la página que acaba de darle el servlet con algunos parámetros para agarrar el archivo de imagen correcta.

<img src="YourServlet?imageFileName=imageNum1">
 0
Author: tinymothbrain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-07 15:15:52

Aquí está mi solución. Es muy simple. La programación de cuadros podría ser mejor.

<!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
Author: Timmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 13:33:14

Fuertemente basado en el código #4 de Doin, el siguiente ejemplo simplifica ese código un poco utilizando document.write en lugar de src en el iframe para soportar CORS. También solo se centra en romper la caché del navegador, no recargar todas las imágenes de la página.

A continuación está escrito en typescript y utiliza el angular $q promise library, solo para su información, pero debería ser lo suficientemente fácil de portar a vanilla javascript. El método está destinado a vivir dentro de una clase typescript.

Devuelve una promesa que será resuelta cuando el iframe haya completado la recarga. No muy probado, pero funciona bien para nosotros.

    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
Author: Victor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 22:39:39

Utilicé el siguiente concepto de enlazar primero la imagen con una url falsa(buffer) y luego enlazar con la url válida.

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + "Buffer.jpg";

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + ".jpg";

De esta manera, estoy forzando al navegador a actualizarse con una url válida.

 0
Author: Prashanth Shivasubramani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-28 10:51:48
<img src='someurl.com/someimage.ext' onload='imageRefresh(this, 1000);'>

A continuación, en algunos 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>

Y lo que esto hace es, cuando la imagen se carga, programa que se vuelva a cargar en 1 segundo. Estoy usando esto en una página con cámaras de seguridad del hogar de diferentes tipos.

 0
Author: J Fields,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-16 16:29:59

El siguiente código es útil para actualizar la imagen cuando se hace clic en un botón.

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')" />
 0
Author: Codemaker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-19 18:16:35