Cómo recargar / actualizar un elemento (imagen) en jQuery

262

¿Es posible volver a cargar una imagen con un nombre de archivo idéntico desde un servidor usando jQuery?

Por ejemplo, tengo una imagen en una página, sin embargo, la imagen física puede cambiar según las acciones del usuario. Tenga en cuenta que esto no significa que el nombre del archivo cambie, sino el archivo en sí.

es decir:

  • El usuario ve la imagen en la página predeterminada
  • El usuario sube una nueva imagen
  • La imagen predeterminada en la página no cambia (supongo que esto se debe a que el nombre del archivo es idéntico, el navegador usa la versión en caché)

Independientemente de la frecuencia con que se llame el siguiente código, el mismo problema persiste.

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

En la documentación de jQuery, la función "cargar" sería perfecta si tuviera un método predeterminado para activar el evento en lugar de vincular una función de devolución de llamada a una carga exitosa / completa de un elemento.

Cualquier ayuda es muy apreciada.

Alexis Abril
fuente
1
@ Alexis, ¿su problema es que la imagen se almacena en caché en el navegador y no se actualizará después de que se haya cambiado en el servidor?
Jay
1
@jeerose, creo que este es el problema, ya que el archivo realmente cambia (mismo nombre de archivo) y se refleja en la página si realiza una actualización completa de la página.
Alexis Abril

Respuestas:

551

Parece que es tu navegador almacenando en caché la imagen (que ahora noto que escribiste en tu pregunta). Puede forzar al navegador a recargar la imagen pasando una variable adicional como esta:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
arrendajo
fuente
1
Agregar una variable de cadena de consulta pasó completamente por mi mente. Esto lo resolvió y la imagen ahora se vuelve a cargar a pedido.
Alexis Abril
45
consejo de gangsta, me encanta
Dave Jellison
44
Funciona, y es una buena solución, ¡pero sigue siendo una solución! ¿No hay una forma diferente de recuperar la imagen que le dice al navegador que se olvide del caché?
spuas
Tengo una cámara web muy exigente que parece prohibir cualquier solicitud de imágenes estáticas que contengan parámetros. Ugh Esta es una gran solución de lo contrario.
dangowans
3
@TomasGonzalez B / c no es una oportunidad de conseguir una colisión con random, y no debe siempre con Datemenos que seas muy, muy rápido. ; ^) Obtener una cita en el cliente no requiere muchos recursos, y puede reutilizar tantas imágenes como necesite de una vez, así que continúe con el paso 4. Beneficio.
ruffin
57

Probablemente no sea la mejor manera, pero he resuelto este problema en el pasado simplemente agregando una marca de tiempo a la URL de la imagen usando JavaScript:

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

La próxima vez que se carga, la marca de tiempo se establece en la hora actual y la URL es diferente, por lo que el navegador realiza una OBTENCIÓN de la imagen en lugar de utilizar la versión en caché.

Kaleb Brasee
fuente
2
Esto funcionó para mí durante años, pero hoy mi servidor de imágenes (no controlado por mí) comenzó a devolver un enlace roto si el nombre del archivo no es exacto. Si alguien tiene otra solución, sería muy apreciado. Lamentablemente, cada respuesta en este hilo es una variación de este.
Felwithe
@felwithe, ¿puede ser que este servidor solo busque la extensión al final de la consulta? Entonces puede intentar probar este enfoque: imagename.jpg?t=1234567&q=.jpgoimagename.jpg#t1234567.jpg
FlameStorm
26

Este podría ser uno de los dos problemas que mencionas.

  1. El servidor está almacenando en caché la imagen.
  2. JQuery no se dispara o al menos no actualiza el atributo

Para ser sincero, creo que es el número dos. Sería mucho más fácil si pudiéramos ver más jQuery. Pero para empezar, intente eliminar el atributo primero y luego configúrelo nuevamente. Solo para ver si eso ayuda:

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

Incluso si esto funciona, publique un código ya que esto no es óptimo, imo :-)

Kordonme
fuente
@Kordonme, ¿es aquí donde alguien comenta sobre jQuery "malo"? (Estoy bromeando, estoy bromeando);)
Jay
@Kordonme, esto en realidad se lleva a cabo en un controlador de eventos y por el momento es la única línea de código. Agregué una alerta justo antes de esta línea para verificar que el evento realmente se está activando. El evento se dispara sin errores.
Alexis Abril
3
Tengo una cámara web muy exigente que parece prohibir cualquier solicitud de imágenes estáticas que contengan parámetros. Ugh Esta es una gran solución para mi caso único. Gracias.
dangowans
Esta es la mejor respuesta si no quiere / necesita parámetros residuales
RafaSashi
Gracias, esto ayudó (solo lo guardó en caché para mí en Chrome)
Daniel Resch
14

con una línea sin preocuparse por codificar la imagen src en javascript (gracias a jeerose por las ideas:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
Radu
fuente
13
Solo tenga cuidado porque esto agregará infinitamente más y más caracteres al final de la URL
Alfo
9

Para evitar el almacenamiento en caché y evitar agregar marcas de tiempo infinitas a la URL de la imagen, elimine la marca de tiempo anterior antes de agregar una nueva, así es como lo hice.

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

¡Esto funciona muy bien! sin embargo, si vuelve a cargar el src varias veces, la marca de tiempo también se concatena con la url. He modificado la respuesta aceptada para lidiar con eso.

$('#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
fuente
3

¿Has intentado restablecer el html de contenedores de imágenes? Por supuesto, si es el navegador el que está almacenando en caché, entonces esto no ayudaría.

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

Algunas veces en realidad una solución como -

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

tampoco actualizar src correctamente, prueba esto, funcionó para mí ->

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

Usar "#" como delimitador puede ser útil

Mis imágenes se guardan en una carpeta "oculta" encima de "www" para que solo los usuarios registrados tengan acceso a ellas. Por esta razón, no puedo usar lo ordinario, <img src=/somefolder/1023.jpg>pero envío solicitudes al servidor como <img src=?1023>y responde respondiendo enviando la imagen guardada con el nombre '1023'.

La aplicación se utiliza para recortar imágenes, por lo que después de una solicitud ajax para recortar la imagen, se cambia como contenido en el servidor pero mantiene su nombre original. Para ver el resultado del recorte, una vez completada la solicitud ajax, la primera imagen se elimina del DOM y se inserta una nueva imagen con el mismo nombre<img src=?1023> .

Para evitar el cobro agrego a la solicitud de la etiqueta de "tiempo" precedidas por "#" por lo que se convierte <img src=?1023#1467294764124>. El servidor filtra automáticamente la parte hash de la solicitud y responde correctamente enviando mi imagen guardada como '1023'. Por lo tanto, siempre obtengo la última versión de la imagen sin mucha decodificación del lado del servidor.

usuario3506298
fuente
1
¿Por qué pasar por tantos problemas para servir una imagen? Parece una molestia sin sentido
lucasreta 05 de
0

Puede que tenga que volver a cargar la fuente de la imagen varias veces. Encontré una solución con Lodash que me funciona bien:

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

Una marca de tiempo existente se truncará y se reemplazará por una nueva.

slp
fuente
-1

Basado en la respuesta de @kasper Taeymans.

Si simplemente necesita recargar la imagen (no reemplazar su src con algo nuevo), intente:

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

Simplemente hago esto en html:

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

Y vuelva a cargar la imagen en el código detrás de esta manera:

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

}

FEl Padrino
fuente
1
Volver a cargar la página y configurar en asp.NET WebForms no es realmente el tema aquí.
Jonas Stensved