Comment forcer un navigateur Web à ne pas mettre en cache les images

Contexte

J’écris et utilise un outil de gestion de contenu très simple basé sur CGI (Perl) pour deux sites Web pro bono. Il fournit à l’administrateur du site des formulaires HTML pour les événements où ils remplissent les champs (date, lieu, titre, description, liens, etc.) et les enregistre. Sur ce formulaire, je permets à l’administrateur de télécharger une image liée à l’événement. Sur la page HTML affichant le formulaire, je montre également un aperçu de l’image téléchargée (balise HTML img).

Le problème

Le problème se produit lorsque l’administrateur souhaite modifier l’image. Il lui suffirait d’appuyer sur le bouton “parcourir”, de choisir une nouvelle image et d’appuyer sur OK. Et cela fonctionne bien.

Une fois l’image téléchargée, mon CGI d’arrière-plan gère le téléchargement et recharge le formulaire correctement.

Le problème est que l’image affichée ne se rafraîchit pas. L’ancienne image est toujours affichée, même si la firebase database contient la bonne image. Je l’ai réduit au fait que l’IMAGE EST CACHÉ dans le navigateur Web. Si l’administrateur appuie sur le bouton RELOAD dans Firefox / Explorer / Safari, tout est rafraîchi et la nouvelle image apparaît.

Ma solution – Ne fonctionne pas

J’essaie de contrôler le cache en écrivant une instruction HTTP Expires avec une date très éloignée par le passé.

Expires: Mon, 15 Sep 2003 1:00:00 GMT 

Rappelez-vous que je suis du côté administratif et que je ne me soucie pas vraiment du chargement des pages, car elles sont toujours expirées.

Mais cela ne fonctionne pas non plus.

Remarques

Lors du téléchargement d’une image, son nom de fichier n’est pas conservé dans la firebase database. Il est renommé en Image.jpg (pour simplement supprimer les choses lors de son utilisation). Lorsque vous remplacez l’image existante par une nouvelle, le nom ne change pas non plus. Juste le contenu du fichier image change.

Le serveur Web est fourni par le service d’hébergement / fournisseur de services Internet. Il utilise Apache.

Question

Existe-t-il un moyen de forcer le navigateur Web à ne PAS mettre en cache les éléments de cette page, même pas les images?

Je jongle avec l’option “enregistrer le nom de fichier” avec la firebase database. De cette manière, si l’image est modifiée, le code SRM de la balise IMG changera également. Cependant, cela nécessite beaucoup de changements sur tout le site et je préfère ne pas le faire si j’ai une meilleure solution. En outre, cela ne fonctionnera toujours pas si la nouvelle image téléchargée porte le même nom (par exemple, si l’image a été légèrement décalée et si elle est à nouveau téléchargée).

Armin Ronacher a la bonne idée. Le problème est que des chaînes aléatoires peuvent entrer en collision. J’utiliserais:

  

où “1222259157.415” est l’heure actuelle sur le serveur. (Remarque: j’ai utilisé time.time () de python pour générer cela)

Correctif simple: attachez une chaîne de requête aléatoire à l’image:

  

Que dit le RFC HTTP:

 Cache-Control: no-cache 

Mais ça ne marche pas très bien 🙂

J’utilise la fonction de temps modifiée par PHP , par exemple:

 echo "; 

Si vous modifiez l’image, la nouvelle image est utilisée plutôt que celle mise en cache, en raison d’un horodatage modifié différent.

J’utiliserais:

  

où “20130910043254” est l’heure de modification du fichier.

Lors du téléchargement d’une image, son nom de fichier n’est pas conservé dans la firebase database. Il est renommé en Image.jpg (pour simplement supprimer les choses lors de son utilisation). Lorsque vous remplacez l’image existante par une nouvelle, le nom ne change pas non plus. Juste le contenu du fichier image change.

Je pense qu’il existe deux types de solutions simples: 1) celles qui viennent en premier à l’esprit (solutions simples, faciles à trouver), 2) celles qui se présentent après reflection (car elles sont faciles à trouver). utilisation). Apparemment, vous ne bénéficierez pas toujours si vous choisissez de réfléchir. Mais la deuxième option est plutôt sous-estimée, je crois. Il suffit de penser pourquoi php est si populaire;)

Vous pouvez écrire un script proxy pour servir des images – mais c’est un peu plus compliqué. Quelque chose aime ça:

HTML:

  

Scénario:

 // PHP if( isset( $_GET['img'] ) && is_file( IMG_PATH . $_GET['img'] ) ) { // read contents $f = open( IMG_PATH . $_GET['img'] ); $img = $f.read(); $f.close(); // no-cache headers - complete set // these copied from [php.net/header][1], tested myself - works header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Some time in the past header("Last-Modified: " . gmdate("D, d MYH:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); // image related headers header('Accept-Ranges: bytes'); header('Content-Length: '.strlen( $img )); // How many bytes we're going to send header('Content-Type: image/jpeg'); // or image/png etc // actual image echo $img; exit(); } 

En fait, soit les en-têtes no-cache, soit le nombre aléatoire à l’image src devraient être suffisants, mais puisque nous voulons être à l’épreuve des balles.

Je suis un NOUVEAU codeur, mais voici ce que j’ai imaginé: empêcher le navigateur de mettre en cache et de conserver les vues de ma webcam:

          

Vous ne savez pas ce qui fonctionne sur ce navigateur, mais cela fonctionne pour certains: IE: Fonctionne lorsque la page Web est actualisée et lorsque le site Web est revisité (sans rafraîchissement). CHROME: Fonctionne uniquement lorsque la page Web est actualisée (même après une nouvelle visite). SAFARI et iPad: Ne fonctionne pas, je dois effacer l’historique et les données Web.

Des idées sur SAFARI / iPad?

Lors du téléchargement d’une image, son nom de fichier n’est pas conservé dans la firebase database. Il est renommé en Image.jpg (pour simplement supprimer les choses lors de son utilisation).

Changez cela et vous avez corrigé votre problème. J’utilise les horodatages, comme avec les solutions proposées ci-dessus: Image- .jpg

Vraisemblablement, tous les problèmes que vous évitez en gardant le même nom de fichier pour l’image peuvent être surmontés, mais vous ne dites pas ce qu’ils sont.

utiliser Class = “NO-CACHE”

échantillon html:

 

jQuery:

  $(document).ready(function () { $('.NO-CACHE').attr('src',function () { return $(this).attr('src') + "?a=" + Math.random() }); }); 

javascript:

 var nods = document.getElementsByClassName('NO-CACHE'); for (var i = 0; i < nods.length; i++) { nods[i].attributes['src'].value += "?a=" + Math.random(); } 

Résultat: src = "images / img1.jpg" => src = "images / img1.jpg? A = 0.08749723793963926"

Votre problème est que, malgré l’en Expires: tête Expires: :, votre navigateur réutilise sa copie en mémoire de l’image avant sa mise à jour, plutôt que de vérifier son cache.

J’ai eu une situation très similaire en téléchargeant des images de produit dans le backend d’administration pour un site de type magasin, et dans mon cas, la meilleure option était d’utiliser javascript pour forcer une actualisation d’image sans utiliser d’autres techniques de modification d’URL. ont déjà mentionné ici. Au lieu de cela, je mets l’URL de l’image dans un IFRAME masqué, appelé location.reload(true) dans la fenêtre de l’IFRAME, puis j’ai remplacé mon image sur la page. Cela force le rafraîchissement de l’image, pas seulement sur la page que je visite, mais aussi sur les pages ultérieures que je visite, sans que le client ou le serveur ait à mémoriser les parameters de chaîne de requête URL ou d’identificateur de fragment.

J’ai posté du code pour le faire dans ma réponse ici .

J’ai vérifié toutes les réponses sur le Web et le meilleur semblait être: (en fait ce n’est pas le cas)

  

en premier.

Cependant, si vous ajoutez le paramètre cache = none (qui est un mot statique “none”), cela n’affecte en rien, le navigateur charge toujours depuis le cache.

La solution à ce problème était:

  

où vous ajoutez fondamentalement un timestamp unix pour rendre le paramètre dynamic et pas de cache, cela a fonctionné.

Cependant, mon problème était un peu différent: je chargeais à la volée une image de graphique php générée et contrôlais la page avec les parameters $ _GET. Je voulais que l’image soit lue à partir du cache lorsque le paramètre URL GET rest le même et ne cache pas lorsque les parameters GET changent.

Pour résoudre ce problème, je devais hacher $ _GET mais comme c’est un tableau, voici la solution:

 $chart_hash = md5(implode('-', $_GET)); echo ""; 

Modifier :

Bien que la solution ci-dessus fonctionne correctement, vous souhaitez parfois diffuser la version en cache JUSQU’À ce que le fichier soit modifié. (avec la solution ci-dessus, cela désactive complètement le cache pour cette image) Donc, pour diffuser l’image en cache à partir du navigateur jusqu’à ce que l’utilisation du fichier image change:

 echo ""; 

filemtime () obtient l’heure de modification du fichier.

Avec le potentiel de proxy transparents mal comportés entre vous et le client, le seul moyen de garantir totalement que les images ne seront pas mises en cache est de leur donner un URI unique, quelque chose comme marquer un horodatage en tant que chaîne de requête ou chemin.

Si cet horodatage correspond à la dernière heure de mise à jour de l’image, vous pouvez alors mettre en cache lorsque nécessaire et servir la nouvelle image au bon moment.

Je suppose que la question originale concerne les images stockées avec des informations textuelles. Donc, si vous avez access à un contexte de texte lors de la génération de l’URL src = …, pensez à stocker / utiliser CRC32 d’octets d’image au lieu d’un horodatage ou d’un horodatage sans signification. Ensuite, si la page contenant de nombreuses images est affichée, seules les images mises à jour seront rechargées. Finalement, si le stockage de CRC est impossible, il peut être calculé et ajouté à l’URL lors de l’exécution.

Ajouter un horodatage

donnera toujours à votre fichier un nombre aléatoire à la fin et arrêtera la mise en cache

De mon sharepoint vue, désactiver la mise en cache des images est une mauvaise idée. Du tout.

Le problème fondamental ici est de savoir comment forcer le navigateur à mettre à jour l’image lorsque celle-ci a été mise à jour côté serveur.

Encore une fois, de mon sharepoint vue personnel, la meilleure solution consiste à désactiver l’access direct aux images. Au lieu de cela, accédez aux images via un filtre / servlet / côté serveur ou d’autres outils / services similaires.

Dans mon cas, c’est un service de repos, qui renvoie une image et attache ETag en réponse. Le service conserve le hachage de tous les fichiers, si le fichier est modifié, le hachage est mis à jour. Il fonctionne parfaitement dans tous les navigateurs modernes. Oui, il faut du temps pour le mettre en œuvre, mais cela en vaut la peine.

La seule exception – sont les favicons. Pour certaines raisons, cela ne fonctionne pas. Je ne pouvais pas forcer le navigateur à mettre à jour son cache côté serveur. ETags, Cache Control, Expires, Pragma, rien n’a aidé.

Dans ce cas, l’ajout de parameters random / version dans l’URL semble être la seule solution.