J'accède à un lien sur mon site qui fournira une nouvelle image à chaque accès.
Le problème que je rencontre est que si j'essaie de charger l'image en arrière-plan puis de mettre à jour celle sur la page, l'image ne change pas - bien qu'elle soit mise à jour lorsque je recharge la page.
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);
}
En-têtes tels que FireFox les voit:
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
J'ai besoin de forcer un rafraîchissement de cette image uniquement sur la page. Des idées?
javascript
image
url
refresh
QueueHammer
la source
la source
Réponses:
Essayez d'ajouter un brise-cache à la fin de l'URL:
Cela ajoutera automatiquement l'horodatage actuel lorsque vous créez l'image, et cela fera que le navigateur recherchera à nouveau l'image au lieu de récupérer celle du cache.
la source
'image.jpg?' + (+new Date())
Date.now()
pour celaMath.random()
J'ai vu beaucoup de variations dans les réponses sur la façon de procéder, alors j'ai pensé les résumer ici (plus ajouter une 4ème méthode de ma propre invention):
(1) Ajoutez un paramètre de requête de contournement du cache unique à l'URL, tel que:
Avantages: 100% fiable, rapide et facile à comprendre et à mettre en œuvre.
Inconvénients: contourne complètement la mise en cache, ce qui signifie des retards inutiles et une utilisation de la bande passante chaque fois que l'image ne change pas entre les vues. Remplira potentiellement le cache du navigateur (et les caches intermédiaires) avec de très nombreuses copies d'exactement la même image! En outre, nécessite la modification de l'URL de l'image.
Quand l'utiliser: à utiliser lorsque l'image change constamment, comme pour un flux webcam en direct. Si vous utilisez cette méthode, assurez-vous de servir les images elles-mêmes avec
Cache-control: no-cache
des en-têtes HTTP !!! (Souvent, cela peut être configuré à l'aide d'un fichier .htaccess). Sinon, vous remplissez progressivement les caches avec d'anciennes versions de l'image!(2) Ajoutez un paramètre de requête à l'URL qui ne change que lorsque le fichier le fait, par exemple:
(C'est du code PHP côté serveur, mais le point important ici est juste qu'une chaîne de requête ? M = [heure de la dernière modification du fichier] est ajoutée au nom du fichier).
Avantages: 100% fiable, rapide et facile à comprendre et à mettre en œuvre, et préserve parfaitement les avantages de la mise en cache.
Inconvénients: nécessite de modifier l'URL de l'image. En outre, un peu plus de travail pour le serveur - il doit avoir accès à l'heure de dernière modification du fichier. Exige également des informations côté serveur, donc ne convient pas à une solution purement côté client uniquement pour rechercher une image actualisée.
Quand l'utiliser: lorsque vous souhaitez mettre en cache des images, mais que vous devrez peut-être les mettre à jour à la fin du serveur de temps en temps sans changer le nom du fichier lui-même. ET lorsque vous pouvez facilement vous assurer que la chaîne de requête correcte est ajoutée à chaque instance d'image dans votre code HTML.
(3) Serve vos images avec l' en- tête
Cache-control: max-age=0, must-revalidate
et ajouter un cadre unique memcache identifiant fragment -busting à l'URL, tels que:L'idée ici est que l'en-tête de contrôle du cache place les images dans le cache du navigateur, mais les marque immédiatement périmées, de sorte que chaque fois qu'elles sont ré-affichées, le navigateur doit vérifier avec le serveur pour voir si elles ont changé. Cela garantit que le cache HTTP du navigateur renvoie toujours la dernière copie de l'image. Cependant, les navigateurs réutilisent souvent une copie en mémoire d'une image s'ils en ont une, et ne vérifient même pas leur cache HTTP dans ce cas. Pour éviter cela, un identifiant de fragment est utilisé: la comparaison des images en mémoire
src
inclut l'identificateur de fragment, mais il est supprimé avant d'interroger le cache HTTP. (Ainsi, par exemple,image.jpg#A
etimage.jpg#B
peuvent tous deux être affichés à partir de l'image.jpg
entrée dans le cache HTTP du navigateur, maisimage.jpg#B
ne serait jamais affiché en utilisant les données d'image conservées en mémoire depuis laimage.jpg#A
dernière fois).Avantages: utilise correctement les mécanismes de mise en cache HTTP et utilise les images mises en cache si elles n'ont pas changé. Fonctionne pour les serveurs qui s'étouffent avec une chaîne de requête ajoutée à une URL d'image statique (puisque les serveurs ne voient jamais les identificateurs de fragments - ils sont réservés à l'usage exclusif des navigateurs).
Inconvénients: repose sur le comportement quelque peu douteux (ou du moins mal documenté) des navigateurs, en ce qui concerne les images avec des identificateurs de fragment dans leurs URL (Cependant, j'ai testé cela avec succès dans FF27, Chrome33 et IE11). Envoie toujours une demande de revalidation au serveur pour chaque vue d'image, ce qui peut être excessif si les images ne changent que rarement et / ou la latence est un gros problème (car vous devez attendre la réponse de revalidation même lorsque l'image mise en cache est toujours bonne) . Nécessite de modifier les URL des images.
Quand l'utiliser: à utiliser lorsque les images peuvent changer fréquemment ou doivent être actualisées par intermittence par le client sans implication de script côté serveur, mais là où vous voulez toujours l'avantage de la mise en cache. Par exemple, interroger une webcam en direct qui met à jour une image de manière irrégulière toutes les quelques minutes. Vous pouvez également utiliser au lieu de (1) ou (2) si votre serveur n'autorise pas les chaînes de requête sur les URL d'images statiques.
(4) Rafraîchissez de force une image particulière en utilisant Javascript, en la chargeant d'abord dans un fichier caché
<iframe>
puis en appelantlocation.reload(true)
les iframescontentWindow
.Les étapes sont les suivantes:
Chargez l'image à rafraîchir dans une iframe cachée. Il ne s'agit que d'une étape de configuration - elle peut être effectuée longtemps à l'avance pour l'actualisation réelle, si vous le souhaitez. Peu importe que l'image ne se charge pas à ce stade!
Une fois cela fait, videz toutes les copies de cette image sur vos pages ou n'importe où dans n'importe quel nœud DOM (même ceux hors page stockés dans des variables javascript). Cela est nécessaire car le navigateur peut sinon afficher l'image à partir d'une copie en mémoire périmée (IE11 en particulier): vous devez vous assurer que toutes les copies en mémoire sont effacées, avant d'actualiser le cache HTTP. Si un autre code javascript s'exécute de manière asynchrone, vous devrez peut-être également empêcher ce code de créer de nouvelles copies de l'image à actualiser entre-temps.
Appelle
iframe.contentWindow.location.reload(true)
. Celatrue
force un contournement du cache, en rechargeant directement depuis le serveur et en remplaçant la copie en cache existante.Une fois le rechargement terminé, restaurez les images masquées. Ils devraient maintenant afficher la nouvelle version du serveur!
Pour les images du même domaine, vous pouvez charger l'image directement dans l'iframe. Pour les images interdomaines, vous devez à la place charger une page HTML à partir de votre domaine qui contient l'image dans une
<img>
balise, sinon vous obtiendrez une erreur «Accès refusé» lors de la tentative d'appeliframe.contentWindow.reload(...)
.Avantages: Fonctionne exactement comme la fonction image.reload () que vous souhaitez que le DOM ait! Permet aux images d'être mises en cache normalement (même avec des dates d'expiration futures si vous le souhaitez, évitant ainsi une revalidation fréquente). Vous permet d'actualiser une image particulière sans modifier les URL de cette image sur la page actuelle ou sur toute autre page, en utilisant uniquement du code côté client.
Inconvénients: repose sur Javascript. Il n'est pas garanti à 100% de fonctionner correctement dans tous les navigateurs (j'ai testé cela avec succès dans FF27, Chrome33 et IE11). Très compliqué par rapport aux autres méthodes.
Quand l'utiliser: lorsque vous avez une collection d'images essentiellement statiques que vous souhaitez mettre en cache, mais vous devez toujours pouvoir les mettre à jour de temps en temps et obtenir un retour visuel immédiat que la mise à jour a eu lieu. (Surtout lorsque le rafraîchissement de la page entière du navigateur ne fonctionnerait pas, comme dans certaines applications Web construites sur AJAX par exemple). Et lorsque les méthodes (1) - (3) ne sont pas réalisables car (pour une raison quelconque), vous ne pouvez pas modifier toutes les URL susceptibles d'afficher l'image que vous devez mettre à jour. (Notez que l'utilisation de ces 3 méthodes l'image sera actualisée, mais si une autre page essaie ensuite d'afficher cette image sans la chaîne de requête ou l'identificateur de fragment approprié, elle peut afficher une version plus ancienne à la place).
Les détails de la mise en œuvre d'une manière fée robuste et flexible sont donnés ci-dessous:
Supposons que votre site contient un pixel blanc 1x1 .gif sur le chemin d'URL
/img/1x1blank.gif
, et a également le script PHP d' une ligne suivante (uniquement pour l' application de rafraîchissement forcé de interdomaines images, et peuvent être réécrites dans un langage de script côté serveur , bien sûr) sur le chemin URL/echoimg.php
:Ensuite, voici une implémentation réaliste de la façon dont vous pourriez faire tout cela en Javascript. Cela semble un peu compliqué, mais il y a beaucoup de commentaires, et la fonction importante est juste forceImgReload () - les deux premières images juste vides et non vides, et devraient être conçues pour fonctionner efficacement avec votre propre HTML, alors codez-les comme fonctionne mieux pour vous; une grande partie des complications peuvent être inutiles pour votre site Web:
Ensuite, pour forcer un rafraîchissement d'une image située sur le même domaine que votre page, vous pouvez simplement faire:
Pour rafraîchir une image ailleurs (interdomaine):
Une application plus avancée pourrait être de recharger une image après avoir téléchargé une nouvelle version sur votre serveur, en préparant la phase initiale du processus de rechargement simultanément avec le téléchargement, afin de minimiser le délai de rechargement visible pour l'utilisateur. Si vous effectuez le téléchargement via AJAX et que le serveur renvoie un tableau JSON très simple [succès, largeur, hauteur], votre code pourrait ressembler à ceci:
Une dernière note: bien que cette rubrique concerne les images, elle s'applique potentiellement à d'autres types de fichiers ou de ressources. Par exemple, empêcher l'utilisation de scripts obsolètes ou de fichiers css, ou peut-être même actualiser des documents PDF mis à jour (en utilisant (4) uniquement s'il est configuré pour s'ouvrir dans le navigateur). La méthode (4) peut nécessiter certaines modifications du javascript ci-dessus, dans ces cas.
la source
image.jpg#123
enimage.jpg#124
(ou autre, tant que le bit après le '#' change). Pourriez-vous clarifier ce que vous rechargez et pourquoi?contentWindow
via javascript pour faire l'reload(true)
appel qui est la partie critique de la méthode ... donc non, méthode (4 ) ne fonctionnera pas pour le contenu interdomaine. Bien repéré; Je mettrai à jour les "inconvénients" pour l'inclure.Comme alternative à ...
...Il paraît que...
... est suffisant pour tromper le cache du navigateur sans contourner les caches en amont, en supposant que vous ayez renvoyé les en-
Cache-Control
têtes corrects . Bien que vous puissiez utiliser ...... vous perdez les avantages des en- têtes
If-Modified-Since
ouIf-None-Match
, donc quelque chose comme ...... devrait empêcher le navigateur de télécharger à nouveau l'image entière si elle n'a pas réellement changé. Testé et fonctionnant sur IE, Firefox et Chrome. Malheureusement, il échoue sur Safari, sauf si vous utilisez ...
... bien que cela puisse être préférable au remplissage de caches en amont avec des centaines d'images identiques, en particulier lorsqu'elles s'exécutent sur votre propre serveur. ;-)
Mettre à jour (2014-09-28): De nos jours, il semble également
Cache-Control: no-store
nécessaire pour Chrome.la source
src
attribut complet , donc l'ajout d'un identifiant de fragment unique garantit que l'image n'est pas simplement extraite de la mémoire. Mais les identifiants de fragment ne sont pas envoyés dans le cadre des requêtes HTTP, donc le cache HTTP normal sera utilisé normalement. C'est pourquoi cette technique fonctionne.Cache-Control: max-age=0, must-revalidate
c'est bon pour moi?newImage.src = "http://localhost/image.jpg#" + i++;
Après avoir créé la nouvelle image, supprimez-vous l'ancienne image du DOM et la remplacez-vous par la nouvelle?
Vous pouvez récupérer de nouvelles images à chaque appel de updateImage, mais ne pas les ajouter à la page.
Il existe plusieurs façons de procéder. Quelque chose comme ça marcherait.
Après l'avoir fait fonctionner, s'il y a encore des problèmes, c'est probablement un problème de mise en cache comme les autres réponses en parlent.
la source
Une réponse consiste à ajouter de manière piratée certains paramètres de requête get comme cela a été suggéré.
Une meilleure réponse consiste à émettre quelques options supplémentaires dans votre en-tête HTTP.
En fournissant une date dans le passé, elle ne sera pas mise en cache par le navigateur.
Cache-Control
a été ajouté dans HTTP / 1.1 et la balise must-revalidate indique que les proxys ne devraient jamais servir une ancienne image même dans des circonstances atténuantes, et cePragma: no-cache
n'est pas vraiment nécessaire pour les navigateurs / caches modernes actuels, mais peut aider avec certaines anciennes implémentations cassées.la source
J'avais une exigence: 1) je ne peux pas en ajouter
?var=xx
à l'image 2) cela devrait fonctionner entre les domainesJ'aime vraiment l'option # 4 dans cette réponse avec une mais:
Ma façon rapide et sale est:
iframe.contentWindow.location.reload(true);
C'est ici
Ouais, je sais, setTimeout ... Vous devez changer cela en événements onload appropriés.
la source
Puis ci-dessous dans certains javascript
Et donc ce que cela fait, lorsque l'image se charge, la planifie pour être rechargée en 1 seconde. J'utilise ceci sur une page avec des caméras de sécurité à domicile de types différents.
la source
Ce que j'ai fini par faire, c'est que le serveur mappe toute demande d'image dans ce répertoire vers la source que j'essayais de mettre à jour. J'ai ensuite fait ajouter un chiffre à la fin du nom à mon temporisateur pour que le DOM le voit comme une nouvelle image et le charge.
Par exemple
demandera le même code de génération d'image, mais il ressemblera à des images différentes pour le navigateur.
la source
la source
../showImage.phpFri May 01 2015 17:34:18 GMT+0200 (Mitteleuropäische Sommerzeit)
soit un nom de fichier valide ... Au moins, c'est ce qu'il essaie de charger ...path='../showImage.php';
pourpath='../showImage.php?';
définir son propre src comme src.
la source
Essayez d'utiliser une chaîne de requête sans valeur pour en faire une URL unique:
la source
Fortement basé sur le code n ° 4 de Doin, l'exemple ci-dessous simplifie beaucoup ce code en l'utilisant
document.write
au lieu desrc
leiframe
pour prendre en charge CORS. Se concentre également uniquement sur la destruction du cache du navigateur, et non sur le rechargement de chaque image de la page.Ci-dessous est écrit
typescript
et utilise leangular
$ q bibliothèque promise, juste fyi, mais devrait être assez facile à porter en javascript vanilla. La méthode est destinée à vivre à l'intérieur d'une classe tapuscrit.Renvoie une promesse qui sera résolue lorsque l'iframe aura terminé le rechargement. Pas lourdement testé, mais fonctionne bien pour nous.
la source
+ encodeURI(src) +
pour vous échapper correctementsrc
dans leiframe
.Le code suivant est utile pour actualiser l'image lorsqu'un bouton est cliqué.
la source
J'ai résolu ce problème en renvoyant les données via une servlet.
Ensuite, à partir de la page, vous lui donnez simplement le servlet avec quelques paramètres pour récupérer le fichier image correct.
la source
Voici ma solution. C'est très simple. La programmation des trames pourrait être meilleure.
la source
Pas besoin de
new Date().getTime()
manigances. Vous pouvez tromper le navigateur en ayant une image factice invisible et en utilisant jQuery .load (), puis en créant une nouvelle image à chaque fois:la source
Solution simple: ajoutez cet en-tête à la réponse:
Pourquoi cela fonctionne est clairement expliqué sur cette page faisant autorité: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
Il explique également pourquoi
no-cache
ne fonctionne pas.Les autres réponses ne fonctionnent pas car:
Caching.delete
concerne un nouveau cache que vous pouvez créer pour un travail hors ligne, voir: https://web.dev/cache-api-quick-guide/Les fragments utilisant un # dans l'URL ne fonctionnent pas car le # indique au navigateur de ne pas envoyer de demande au serveur.
Un cache-buster avec une partie aléatoire ajoutée à l'url fonctionne, mais remplira également le cache du navigateur. Dans mon application, je voulais télécharger une image de 5 Mo toutes les quelques secondes à partir d'une webcam. Cela ne prendra qu'une heure ou moins pour geler complètement votre PC. Je ne sais toujours pas pourquoi le cache du navigateur n'est pas limité à un maximum raisonnable, mais c'est certainement un inconvénient.
la source
J'ai amélioré le script d' AlexMA pour montrer ma webcam sur une page Web qui télécharge périodiquement une nouvelle image avec le même nom. J'ai eu des problèmes que l'image scintillait parfois en raison d'une image cassée ou d'une image chargée (incomplète). Pour éviter le scintillement, je vérifie la hauteur naturelle de l'image car la taille de l'image de ma webcam n'a pas changé. Ce n'est que si la hauteur de l'image chargée correspond à la hauteur de l'image d'origine que l'image complète sera affichée sur la page.
la source
J'ai utilisé le concept ci-dessous de lier d'abord l'image avec une fausse URL (tampon) et de la lier ensuite avec l'URL valide.
De cette façon, je force le navigateur à se rafraîchir avec une URL valide.
la source