Como recarregar / atualizar um elemento (imagem) no jQuery

262

É possível recarregar uma imagem com um nome de arquivo idêntico de um servidor usando jQuery?

Por exemplo, eu tenho uma imagem em uma página, no entanto, a imagem física pode mudar com base nas ações do usuário. Observe que isso não significa que o nome do arquivo seja alterado, mas o próprio arquivo real.

ou seja:

  • O usuário visualiza a imagem na página padrão
  • Usuário envia nova imagem
  • A imagem padrão na página não muda (suponho que isso seja devido ao nome do arquivo ser idêntico, o navegador usa a versão em cache)

Independentemente da frequência com que o código abaixo é chamado, o mesmo problema persiste.

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

Na documentação do jQuery, a função "load" seria perfeita se tivesse um método padrão de acionar o evento, em vez de vincular uma função de retorno de chamada a uma carga completa / bem-sucedida de um elemento.

Qualquer assistência é muito apreciada.

Alexis Abril
fonte
1
@ Alexis, o seu problema é que a imagem é armazenada em cache no navegador e não será atualizada depois de alterada no servidor?
jay
1
@jeerose, acredito que esse é o problema, pois o arquivo realmente muda (mesmo nome de arquivo) e é refletido na página se você fizer uma atualização completa da página.
Alexis Abril

Respostas:

551

Parece que seu navegador está armazenando em cache a imagem (que agora notei que você escreveu em sua pergunta). Você pode forçar o navegador a recarregar a imagem passando uma variável extra da seguinte maneira:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
Jay
fonte
1
Adicionar uma variável de cadeia de consulta passou completamente pela minha cabeça. Isso resolveu e a imagem agora é recarregada a pedido.
Alexis Abril
45
dica de gangsta, adorei
Dave Jellison
4
Funciona e é uma boa solução alternativa, mas ainda uma solução alternativa! Não existe uma maneira diferente de buscar a imagem dizendo ao navegador para esquecer a imagem em cache?
spuas
Eu tenho uma webcam realmente exigente que parece proibir qualquer solicitação de imagens estáticas que contenham parâmetros. Ugh. Esta é uma ótima solução caso contrário.
dangowans
3
@TomasGonzalez B / c lá é uma chance de conseguir uma colisão com random, e não deve nunca ser com Datemenos que você é realmente muito rápido. ; ^) A obtenção de uma data no cliente não consome muitos recursos e você pode reutilizar quantas imagens precisar para obter de uma só vez, então vá para a etapa 4. Lucro.
Ruffin
57

Provavelmente não é a melhor maneira, mas resolvi esse problema no passado simplesmente anexando um carimbo de data / hora ao URL da imagem usando JavaScript:

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

Na próxima vez que carregar, o carimbo de data e hora será definido como o horário atual e o URL será diferente; portanto, o navegador fará um GET para a imagem em vez de usar a versão em cache.

Kaleb Brasee
fonte
2
Isso funcionou para mim por anos, mas hoje meu servidor de imagens (não controlado por mim) começou a retornar um link quebrado se o nome do arquivo não for exato. Se alguém tiver outra solução alternativa, seria muito apreciada. Infelizmente, todas as respostas neste tópico são uma variação deste.
Feltro #
@felwithe, este servidor pode procurar apenas extensão no final da consulta? Então você pode tentar testar esta abordagem: imagename.jpg?t=1234567&q=.jpgouimagename.jpg#t1234567.jpg
FlameStorm
26

Este pode ser um dos dois problemas que você mencionou.

  1. O servidor está armazenando em cache a imagem
  2. O jQuery não dispara ou pelo menos não atualiza o atributo

Para ser sincero, acho que é o número dois. Seria muito mais fácil se pudéssemos ver mais jQuery. Mas, para começar, tente remover o atributo primeiro e, em seguida, defina-o novamente. Só para ver se isso ajuda:

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

Mesmo que isso funcione, poste algum código, pois isso não é o ideal, imo :-)

Kordonme
fonte
@ Kordonme, é aqui que alguém comenta sobre o jQuery "ruim"? (Estou brincando, estou brincando);)
jay
@ Kordonme, isso é realmente realizado em um manipulador de eventos e no momento é a única linha de código. Adicionei um alerta antes dessa linha apenas para verificar se o evento está realmente disparando. O evento é disparado sem erros.
Alexis Abril
3
Eu tenho uma webcam muito exigente que parece proibir qualquer solicitação de imagens estáticas que contenham parâmetros. Ugh. Esta é uma ótima solução para o meu caso único. Obrigado.
dangowans
Esta é a melhor resposta se você não quiser / precisar parâmetros residuais
RafaSashi
Graças Isso ajudou (só em cache para mim no Chrome)
Daniel Resch
14

com uma linha sem se preocupar em codificar a imagem src no javascript (obrigado a jeerose pelas idéias:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
Radu
fonte
13
Apenas tome cuidado, pois isso adicionará infinitamente mais caracteres ao final do URL.
Alfo
9

Para ignorar o cache e evitar adicionar carimbos de data e hora infinitos ao URL da imagem, retire o carimbo de data e hora anterior antes de adicionar um novo, é assim que eu fiz.

//refresh the image every 60seconds
var xyro_refresh_timer = setInterval(xyro_refresh_function, 60000);

function xyro_refresh_function(){
//refreshes an image with a .xyro_refresh class regardless of caching
    //get the src attribute
    source = jQuery(".xyro_refresh").attr("src");
    //remove previously added timestamps
    source = source.split("?", 1);//turns "image.jpg?timestamp=1234" into "image.jpg" avoiding infinitely adding new timestamps
    //prep new src attribute by adding a timestamp
    new_source = source + "?timestamp="  + new Date().getTime();
    //alert(new_source); //you may want to alert that during developement to see if you're getting what you wanted
    //set the new src attribute
    jQuery(".xyro_refresh").attr("src", new_source);
}
nunca
fonte
6

Isso funciona muito bem! no entanto, se você recarregar o src várias vezes, o carimbo de data e hora também será concatenado no URL. Eu modifiquei a resposta aceita para lidar com isso.

$('#image_reload_button').on('click', function () {
    var img = $('#your_image_selector');
    var src = img.attr('src');
    var i = src.indexOf('?dummy=');
    src = i != -1 ? src.substring(0, i) : src;

    var d = new Date();
    img.attr('src', src + '?dummy=' + d.getTime());
});
kasper Taeymans
fonte
3

Você já tentou redefinir o HTML dos contêineres de imagens. Obviamente, se é o navegador que está armazenando em cache, isso não ajudaria.

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

Algumas vezes, na verdade, solução como -

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

também não atualizar src corretamente, tente isso, funcionou para mim ->

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

Usar "#" como um delimitador pode ser útil

Minhas imagens são mantidas em uma pasta "oculta" acima de "www", para que apenas usuários logados tenham acesso a elas. Por esse motivo, não posso usar o comum, <img src=/somefolder/1023.jpg>mas envio solicitações para o servidor <img src=?1023>e ele responde enviando de volta a imagem mantida sob o nome '1023'.

O aplicativo é usado para o corte de imagens; portanto, após uma solicitação do ajax para cortar a imagem, ela é alterada como conteúdo no servidor, mas mantém seu nome original. Para ver o resultado do corte, após a solicitação do ajax ser concluída, a primeira imagem é removida do DOM e uma nova imagem é inserida com o mesmo nome <img src=?1023>.

Para evitar descontar, adiciono à solicitação a tag "time" precedida de "#" para que se torne como <img src=?1023#1467294764124>. O servidor filtra automaticamente a parte de hash da solicitação e responde corretamente enviando de volta minha imagem mantida como '1023'. Assim, sempre recebo a última versão da imagem sem muita decodificação no servidor.

user3506298
fonte
1
Por que passar por todo esse problema para servir uma imagem? Parece ser um aborrecimento sem sentido
lucasreta
0

Talvez eu precise recarregar a fonte da imagem várias vezes. Encontrei uma solução com a Lodash que funciona bem para mim:

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

Um registro de data e hora existente será truncado e substituído por um novo.

slp
fonte
-1

Com base na resposta de @kasper Taeymans.

Se você simplesmente precisar recarregar a imagem (não substitua src pelo smth new), tente:

$(function() {
  var img = $('#img');

  var refreshImg = function(img) {
    // the core of answer is 2 lines below
    var dummy = '?dummy=';
    img.attr('src', img.attr('src').split(dummy)[0] + dummy + (new Date()).getTime());

    // remove call on production
    updateImgVisualizer();
  };


  // for display current img url in input
  // for sandbox only!
  var updateImgVisualizer = function() {
    $('#img-url').val(img.attr('src'));
  };

  // bind img reload on btn click
  $('.img-reloader').click(function() {
    refreshImg(img);
  });

  // remove call on production
  updateImgVisualizer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="img" src="http://dummyimage.com/628x150/">


<p>
  <label>
    Current url of img:
    <input id="img-url" type="text" readonly style="width:500px">
  </label>
</p>

<p>
  <button class="img-reloader">Refresh</button>
</p>

userlond
fonte
-2

Eu simplesmente faço isso em html:

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

E recarregue a imagem no código por trás assim:

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

}

FTheGodfather
fonte
1
Recarregar a página e a configuração no asp.NET WebForms não está realmente no tópico aqui.
Jonas Stensved 8/16