javascript with Atualizar a imagem com uma nova no mesmo URL



title html css (13)

Eu já vi muita variação nas respostas de como fazer isso, então eu pensei em resumi-las aqui (e adicionar um 4º método da minha própria invenção):

(1) Adicione um parâmetro de consulta de impedimento de cache exclusivo ao URL, como:

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

Prós: 100% confiável, rápido e fácil de entender e implementar.

Contras: ignora o armazenamento em cache, o que significa atrasos desnecessários e uso da largura de banda sempre que a imagem não muda entre as visualizações. Encherá potencialmente o cache do navegador (e todos os caches intermediários) com muitas, muitas cópias da mesma imagem! Além disso, requer a modificação do URL da imagem.

Quando usar: Use quando a imagem está em constante mudança, como para um feed de webcam ao vivo. Se você usar esse método, certifique-se de exibir as próprias imagens com os cabeçalhos HTTP Cache-control: no-cache !!! (Muitas vezes isso pode ser configurado usando um arquivo .htaccess). Caso contrário, você estará progressivamente preenchendo caches com versões antigas da imagem!

(2) Adicione um parâmetro de consulta ao URL que muda somente quando o arquivo faz, por exemplo:

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

(Esse é o código do lado do servidor PHP, mas o ponto importante aqui é apenas que um querystring? M = [tempo da última modificação do arquivo] é anexado ao nome do arquivo).

Prós: 100% confiável, rápido e fácil de entender e implementar, e preserva perfeitamente as vantagens do armazenamento em cache.

Contras: Requer modificar o URL da imagem. Além disso, um pouco mais de trabalho para o servidor - ele tem que ter acesso ao tempo da última modificação do arquivo. Além disso, requer informações do lado do servidor, portanto, não é adequado para uma solução somente do lado do cliente para verificar se há uma imagem atualizada.

Quando usar: quando quiser armazenar imagens em cache, mas pode precisar atualizá-las no servidor de vez em quando, sem alterar o nome do arquivo. E quando você pode facilmente garantir que a querystring correta seja adicionada a cada instância de imagem no seu HTML.

(3) Sirva suas imagens com o cabeçalho Cache-control: max-age=0, must-revalidate e adicione um identificador de fragmento de memória variável único ao URL, como:

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

A idéia aqui é que o cabeçalho de controle de cache coloca imagens no cache do navegador, mas imediatamente as torna obsoletas, de modo que, e sempre que forem exibidas novamente, o navegador deve verificar com o servidor para ver se elas foram alteradas. Isso garante que o cache HTTP do navegador sempre retorne a cópia mais recente da imagem. No entanto, os navegadores geralmente reutilizarão uma cópia na memória de uma imagem, se tiverem uma, e nem mesmo verificarão seu cache HTTP nesse caso. Para evitar isso, um identificador de fragmento é usado: Comparação de imagem na memória src inclui o identificador de fragmento, mas é retirado antes de consultar o cache HTTP. (Assim, por exemplo, image.jpg#A e image.jpg#B podem ser exibidos a partir da entrada image.jpg no cache HTTP do navegador, mas image.jpg#B nunca seria exibido usando dados de imagem retidos na memória de quando o image.jpg#A foi exibido pela última vez).

Prós: Faz uso adequado dos mecanismos de armazenamento em cache do HTTP e usa imagens em cache se elas não tiverem sido alteradas. Funciona para servidores que sufocam em uma querystring adicionada a uma URL de imagem estática (uma vez que os servidores nunca veem identificadores de fragmentos - eles são apenas para uso exclusivo dos navegadores).

Contras: Depende de um comportamento duvidoso (ou pelo menos pouco documentado) dos navegadores, no que diz respeito às imagens com identificadores de fragmentos em seus URLs (no entanto, eu testei isso com sucesso em FF27, Chrome33 e IE11). Ainda envia um pedido de revalidação ao servidor para cada visualização de imagem, o que pode ser excessivo se as imagens apenas mudarem raramente e / ou a latência for um grande problema (já que você precisa aguardar a resposta de revalidação mesmo quando a imagem em cache ainda estiver boa) . Requer a modificação de URLs de imagem.

Quando usar: use quando as imagens podem mudar com freqüência ou precisar ser atualizada de forma intermitente pelo cliente sem envolvimento do script do lado do servidor, mas onde você ainda deseja a vantagem do armazenamento em cache. Por exemplo, pesquisando uma webcam ao vivo que atualiza uma imagem de forma irregular a cada poucos minutos. Como alternativa, use em vez de (1) ou (2) se o seu servidor não permitir querystrings em URLs de imagem estática.

(4) Atualize forçosamente uma imagem específica usando JavaScript, primeiro carregando-a em um <iframe> oculto e, em seguida, chamando location.reload(true) na contentWindow do iframe.

Os passos são:

  • Carregue a imagem para ser atualizada em um iframe oculto. Este é apenas um passo de configuração - pode ser feito com bastante antecedência a atualização real, se desejado. Não importa se a imagem não é carregada neste estágio!

  • Uma vez feito isso, apague todas as cópias da imagem na (s) sua (s) página (s) ou em qualquer lugar em qualquer nó DOM (mesmo os fora da página armazenados em variáveis ​​javascript). Isso é necessário porque o navegador pode exibir a imagem de uma cópia obsoleta na memória (especialmente o IE11): É necessário garantir que todas as cópias na memória sejam apagadas antes de atualizar o cache HTTP. Se outro código javascript estiver sendo executado de forma assíncrona, talvez também seja necessário evitar que esse código crie novas cópias da imagem a ser atualizada.

  • Chame iframe.contentWindow.location.reload(true) . O true força um bypass de cache, recarregando diretamente do servidor e sobrescrevendo a cópia em cache existente.

  • Quando terminar de recarregar, restaure as imagens em branco. Eles devem agora exibir a nova versão do servidor!

Para imagens de mesmo domínio, você pode carregar a imagem diretamente no iframe. Para imagens de domínio cruzado, você precisa carregar uma página HTML do seu domínio que contenha a imagem em uma tag <img> ; caso contrário, você receberá um erro "Acesso negado" ao tentar chamar iframe.contentWindow.reload(...) .

Prós: Funciona como a função image.reload () que você deseja que o DOM tenha! Permite que as imagens sejam armazenadas em cache normalmente (mesmo com datas de expiração no futuro, se você quiser, evitando assim a revalidação freqüente). Permite que você atualize uma determinada imagem sem alterar os URLs dessa imagem na página atual ou em outras páginas, usando apenas o código do lado do cliente.

Contras: depende de Javascript. Não 100% garantido para funcionar corretamente em todos os navegadores (testei isso com sucesso em FF27, Chrome33 e IE11). Muito complicado em relação aos outros métodos.

Quando usar: quando você tiver uma coleção de imagens basicamente estáticas que deseja armazenar em cache, mas ainda precisar atualizá-las ocasionalmente e obter um feedback visual imediato de que a atualização ocorreu. (Especialmente quando apenas atualizar a página inteira do navegador não funcionaria, como em alguns aplicativos da Web criados em AJAX, por exemplo). E quando os métodos (1) - (3) não são viáveis ​​porque (por qualquer motivo) você não pode alterar todas as URLs que potencialmente podem exibir a imagem que você precisa ter atualizado. (Observe que, usando esses 3 métodos, a imagem será atualizada, mas se outra página tentar exibir essa imagem sem a querystring ou o identificador de fragmento adequados, ela poderá mostrar uma versão mais antiga).

Os detalhes de implementar isto de uma maneira robusta e flexível de fada são dados abaixo:

Vamos supor que seu site contenha um .gif de 1x1 pixel em branco no caminho da URL /img/1x1blank.gif e também tenha o seguinte script PHP de uma linha (necessário apenas para aplicar a atualização forçada a imagens entre domínios e que possa ser reescrito em qualquer linguagem de script do lado do servidor, é claro) no caminho de URL /echoimg.php :

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

Então, aqui está uma implementação realista de como você pode fazer tudo isso em JavaScript. Parece um pouco complicado, mas há muitos comentários, e a função importante é apenas forceImgReload () - as duas primeiras são apenas imagens em branco e não em branco, e devem ser projetadas para funcionar eficientemente com seu próprio HTML, codifique-as como funciona melhor para você; Muitas das complicações neles podem ser desnecessárias para o seu site:

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

Então, para forçar uma atualização de uma imagem localizada no mesmo domínio da sua página, você pode apenas fazer:

forceImgReload("myimage.jpg");

Para atualizar uma imagem de outro lugar (entre domínios):

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

Um aplicativo mais avançado pode ser recarregar uma imagem depois de fazer o upload de uma nova versão para o servidor, preparando o estágio inicial do processo de recarregamento simultâneo ao upload, para minimizar o atraso de recarregamento visível para o usuário. Se você está fazendo o upload via AJAX, e o servidor está retornando uma matriz JSON muito simples [sucesso, largura, altura], então seu código pode ser algo como isto:

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

Uma nota final: Embora este tópico seja sobre imagens, ele também se aplica a outros tipos de arquivos ou recursos. Por exemplo, evitando o uso de scripts antigos ou arquivos css, ou até mesmo atualizando documentos PDF atualizados (usando (4) somente se configurado para abrir no navegador). O método (4) pode exigir algumas alterações no javascript acima, nestes casos.

Estou acessando um link no meu site que fornecerá uma nova imagem toda vez que for acessada.

O problema que estou enfrentando é que, se eu tentar carregar a imagem em segundo plano e depois atualizar a imagem na página, a imagem não será alterada - embora seja atualizada quando eu recarregar a 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);
}

Cabeçalhos como o FireFox os vê:

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

Eu preciso forçar uma atualização apenas dessa imagem na página. Alguma ideia?


Como uma alternativa para ...

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

...parece que...

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

... é suficiente para enganar o cache do navegador sem ignorar quaisquer caches upstream, supondo que você retornou os cabeçalhos Cache-Control corretos. Embora você possa usar ...

Cache-Control: no-cache, must-revalidate

... você perde os benefícios dos cabeçalhos If-Modified-Since ou If-None-Match , então algo como ...

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

... deve impedir que o navegador baixe novamente a imagem inteira se ela não tiver sido realmente alterada. Testado e trabalhando no IE, Firefox e Chrome. Irritantemente, ele falha no Safari, a menos que você use ...

Cache-Control: no-store

... embora isso ainda seja preferível ao preenchimento de caches upstream com centenas de imagens idênticas, particularmente quando elas estão sendo executadas em seu próprio servidor. ;-)

Atualização (2014-09-28): Hoje em dia, parece que o Cache-Control: no-store é necessário para o Chrome.


Tente usar um querystring inútil para torná-lo um URL exclusivo:

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

Eu tinha um requisito: 1) não pode adicionar qualquer ?var=xx para a imagem 2) deve funcionar entre domínios

Eu realmente gosto da opção nº 4 nesta resposta com uma, mas:

  • ele tem problemas para trabalhar com crossdomain de forma confiável (e requer tocar no código do servidor).

Meu jeito rápido e sujo é:

  1. Criar iframe oculto
  2. Carregue a página atual para ela (sim, a página inteira)
  3. iframe.contentWindow.location.reload(true);
  4. Re-defina a fonte da imagem para si

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

Sim, eu sei, setTimeout ... Você tem que mudar isso para onload-events.


document.getElementById("img-id").src = document.getElementById("img-id").src

defina seu próprio src como seu src.


Uma resposta é adicionar alguns parâmetros de consulta get como foi sugerido.

Uma resposta melhor é emitir algumas opções extras no cabeçalho HTTP.

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

Ao fornecer uma data no passado, ela não será armazenada em cache pelo navegador. Cache-Control foi adicionado no HTTP / 1.1 e a tag must-revalidate indica que os proxies nunca devem servir uma imagem antiga mesmo sob circunstâncias atenuantes, e o Pragma: no-cache não é realmente necessário para os atuais navegadores / caches modernos, mas pode ajudar com algumas implementações antigas quebradas.


O que acabei fazendo foi fazer com que o servidor mapeasse qualquer pedido de uma imagem naquele diretório para a fonte que eu estava tentando atualizar. Em seguida, fiz com que meu timer acrescentasse um número ao final do nome para que o DOM o visualizasse como uma nova imagem e carregasse-o.

Por exemplo

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

solicitará o mesmo código de geração de imagem, mas parecerá com imagens diferentes para o 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);
}

Fortemente baseado no código # 4 de Doin, o exemplo abaixo simplifica muito esse código utilizando em document.writevez de srcno iframeCORS. Também se concentra apenas em impedir o cache do navegador, não recarregando todas as imagens da página.

Abaixo está escrito em typescripte usa a biblioteca promessa angular $q , apenas fyi, mas deve ser fácil o suficiente para portar para o javascript de baunilha. O método destina-se a viver dentro de uma classe datilografada.

Retorna uma promessa que será resolvida quando o iframe for concluído. Não muito testado, mas funciona bem para nós.

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

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')" />


Eu resolvi esse problema enviando os dados de volta por meio de um 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());

Então, a partir da página, você apenas fornece o servlet com alguns parâmetros para capturar o arquivo de imagem correto.

<img src="YourServlet?imageFileName=imageNum1">

Aqui está minha solução. É muito simples. O agendamento de quadros pode ser melhor.

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

Depois de criar a nova imagem, você está removendo a imagem antiga do DOM e a substituindo pela nova?

Você poderia estar pegando novas imagens a cada chamada updateImage, mas não adicionando-as à página.

Existem várias maneiras de fazer isso. Algo assim funcionaria.

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

Depois de obter esse trabalho, se ainda houver problemas, provavelmente é um problema de cache como as outras respostas falam.


O código a seguir é útil para atualizar a imagem quando um botão é clicado.

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')" />




refresh