Comment recharger / rafraîchir un élément (image) dans jQuery

262

Est-il possible de recharger une image avec un nom de fichier identique à partir d'un serveur en utilisant jQuery?

Par exemple, j'ai une image sur une page, cependant, l'image physique peut changer en fonction des actions de l'utilisateur. Remarque, cela ne signifie pas que le nom du fichier change, mais le fichier lui-même.

c'est à dire:

  • L'utilisateur visualise l'image sur la page par défaut
  • L'utilisateur télécharge une nouvelle image
  • L'image par défaut sur la page ne change pas (je suppose que cela est dû au nom de fichier étant identique, le navigateur utilise la version mise en cache)

Quelle que soit la fréquence d'appel du code ci-dessous, le même problème persiste.

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

Dans la documentation jQuery, la fonction "load" serait parfaite si elle avait une méthode par défaut pour déclencher l'événement au lieu de lier une fonction de rappel à une charge réussie / complète d'un élément.

Toute aide est grandement appréciée.

Alexis Abril
la source
1
@Alexis, votre problème est-il que l'image est mise en cache dans le navigateur et ne sera pas mise à jour après avoir été modifiée sur le serveur?
jay
1
@jeerose, je crois que c'est le problème car le fichier change réellement (même nom de fichier) et se reflète sur la page si vous effectuez un rafraîchissement complet de la page.
Alexis Abril

Réponses:

551

Il semble que ce soit votre navigateur qui cache l'image (que je remarque maintenant que vous avez écrit dans votre question). Vous pouvez forcer le navigateur à recharger l'image en passant une variable supplémentaire comme ceci:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());
geai
la source
1
L'ajout d'une variable de chaîne de requête m'a complètement dépassé. Cela l'a résolu et l'image se recharge maintenant sur demande.
Alexis Abril
45
astuce gangsta, j'adore
Dave Jellison
4
Cela fonctionne, et c'est une bonne solution de contournement, mais toujours une solution de contournement! N'y a-t-il pas une autre façon de récupérer l'image en disant au navigateur d'oublier celle mise en cache?
spuas
J'ai une webcam très pointilleuse qui semble interdire toute demande d'images statiques contenant des paramètres. Pouah. C'est une excellente solution sinon.
dangowans
3
@TomasGonzalez B / c il y a une chance d'avoir une collision avec random, et ne devrait jamais être avec à Datemoins que vous ne soyez vraiment très rapide. ; ^) Obtenir une date sur le client ne consomme pas beaucoup de ressources, et vous pouvez réutiliser pour autant d'images que vous avez besoin de les extraire à la fois, alors passez à l'étape 4. Profit.
ruffin
57

Ce n'est probablement pas la meilleure façon, mais j'ai résolu ce problème dans le passé en ajoutant simplement un horodatage à l'URL de l'image en utilisant JavaScript:

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

La prochaine fois qu'il se charge, l'horodatage est défini sur l'heure actuelle et l'URL est différente, de sorte que le navigateur effectue un GET pour l'image au lieu d'utiliser la version mise en cache.

Kaleb Brasee
la source
2
Cela a fonctionné pour moi pendant des années, mais aujourd'hui, mon serveur d'images (non contrôlé par moi) a commencé à renvoyer un lien cassé si le nom du fichier n'est pas exact. Si quelqu'un a une autre solution de contournement, ce serait très apprécié. Malheureusement, chaque réponse dans ce fil est une variation de celle-ci.
felwithe
@felwithe, peut-être que ce serveur ne recherche que l'extension à la fin de la requête? Vous pouvez donc essayer de tester cette approche: imagename.jpg?t=1234567&q=.jpgouimagename.jpg#t1234567.jpg
FlameStorm
26

Cela pourrait être l'un des deux problèmes que vous mentionnez vous-même.

  1. Le serveur met en cache l'image
  2. JQuery ne se déclenche pas ou au moins ne met pas à jour l'attribut

Pour être honnête, je pense que c'est le numéro deux. Ce serait beaucoup plus facile si nous pouvions voir plus de jQuery. Mais pour commencer, essayez de supprimer l'attribut d'abord, puis définissez-le à nouveau. Juste pour voir si ça aide:

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

Même si cela fonctionne, postez du code car ce n'est pas optimal, imo :-)

Kordonme
la source
@Kordonme, est-ce là que quelqu'un commente le "mauvais" jQuery? (Je plaisante, je plaisante);)
jay
@Kordonme, il s'agit en fait d'un gestionnaire d'événements et, pour le moment, c'est la seule ligne de code. J'ai ajouté une alerte juste avant cette ligne pour vérifier que l'événement se déclenche réellement. L'événement se déclenche sans erreur.
Alexis Abril
3
J'ai une webcam très pointilleuse qui semble interdire toute demande d'images statiques contenant des paramètres. Pouah. C'est une excellente solution pour mon cas unique. Merci.
dangowans
C'est la meilleure réponse si vous ne voulez pas / n'avez pas besoin de paramètres résiduels
RafaSashi
Merci, cela a aidé (il ne l'a mis en cache que dans Chrome)
Daniel Resch
14

avec une ligne sans souci de coder en dur l'image src dans le javascript (merci à jeerose pour les idées:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());
Radu
la source
13
Faites
9

Pour contourner la mise en cache et éviter d'ajouter des horodatages infinis à l'URL de l'image, supprimez l'horodatage précédent avant d'en ajouter un nouveau, voici comment je l'ai fait.

//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);
}
rompre
la source
6

Cela fonctionne très bien! cependant, si vous rechargez le src plusieurs fois, l'horodatage est également concaténé à l'url. J'ai modifié la réponse acceptée pour y faire face.

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

Avez-vous essayé de réinitialiser les conteneurs d'images html. Bien sûr, si c'est le navigateur qui met en cache, cela n'aidera pas.

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

Parfois, en fait, une solution comme -

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

aussi pas rafraîchir src correctement, essayez cela, cela a fonctionné pour moi ->

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

L'utilisation de "#" comme délimiteur peut être utile

Mes images sont conservées dans un dossier "caché" au-dessus de "www" afin que seuls les utilisateurs connectés y soient autorisés. Pour cette raison je ne peux pas utiliser l'ordinaire <img src=/somefolder/1023.jpg>mais j'envoie des requêtes au serveur comme <img src=?1023>et il répond en renvoyant l'image conservée sous le nom '1023'.

L'application est utilisée pour le recadrage d'image, donc après une demande ajax pour recadrer l'image, elle est modifiée en tant que contenu sur le serveur mais conserve son nom d'origine. Afin de voir le résultat du recadrage, une fois la requête ajax terminée, la première image est supprimée du DOM et une nouvelle image est insérée avec le même nom <img src=?1023>.

Pour éviter l'encaissement, j'ajoute à la demande la balise "time" précédée de "#" pour qu'elle devienne comme <img src=?1023#1467294764124>. Le serveur filtre automatiquement la partie de hachage de la demande et répond correctement en renvoyant mon image conservée comme '1023'. Ainsi, j'obtiens toujours la dernière version de l'image sans trop de décodage côté serveur.

user3506298
la source
1
Pourquoi se donner tant de mal pour servir une image? On dirait un tracas inutile
lucasreta
0

Il se peut que je doive recharger la source d'image plusieurs fois. J'ai trouvé une solution avec Lodash qui fonctionne bien pour moi:

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

Un horodatage existant sera tronqué et remplacé par un nouveau.

slp
la source
-1

Basé sur la réponse de @kasper Taeymans.

Si vous avez simplement besoin de recharger l'image (ne remplacez pas son src par smth nouveau), essayez:

$(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
la source
-2

Je fais simplement cela en html:

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

Et rechargez l'image en code derrière comme ceci:

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

}

FTheGodfather
la source
1
Recharger la page et paramétrer dans asp.NET WebForms n'est pas vraiment sur le sujet ici.
Jonas Stensved