I am accessing a link on my site that will provide a new image each time it is accessed.
The issue I am running into is that if I try to load the image in the background and then update the one on the page, the image doesn't change--though it is updated when I reload the 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);
}
Headers as FireFox sees them:
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
I need to force a refresh of just that image on the page. Any ideas?
Source: Tips4all
Try adding a cachebreaker at the end of the url:
ReplyDeletenewImage.src = "http://localhost/image.jpg?" + new Date().getTime();
This will append the current timestamp automatically when you are creating the image, and it will make the browser look again for the image instead of retrieving the one in the cache.
What I ended up doing was having the server map any request for an image at that directory to the source that I was trying to update. I then had my timer append a number onto the end of the name so the DOM would see it as a new image and load it.
ReplyDeleteE.g.
http://localhost/image.jpg
//and
http://localhost/image01.jpg
will request the same image generation code but it will look like different images to the browser.
var newImage = new Image();
newImage.src = "http://localhost/image.jpg";
var count = 0;
function updateImage()
{
if(newImage.complete) {
document.getElementById("theText").src = newImage.src;
newImage = new Image();
number++;
newImage.src = "http://localhost/image/id/image" + count + ".jpg";
count += 1;
}
setTimeout(updateImage, 1000);
}
Try using a worthless querystring to make it a unique url:
ReplyDeletefunction updateImage()
{
if(newImage.complete) {
document.getElementById("theText").src = newImage.src;
newImage = new Image();
number++;
newImage.src = "http://localhost/image.jpg?" + new Date();
}
setTimeout(updateImage, 1000);
}
One answer is to hackishly add some get query parameter like has been suggested.
ReplyDeleteA better answer is to emit a couple of extra options in your HTTP header.
Pragma: no-cache
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Cache-Control: no-cache, must-revalidate
By providing a date in the past, it won't be cached by the browser. Cache-Control was added in HTTP/1.1 and the must-revalidate tag indicates that proxies should never serve up an old image even under extenuating circumstances, and the Pragma: no-cache isn't really necessary for current modern browsers/caches but may help with some crufty broken old implementations.
After creating the new image, are you removing the old image from the DOM and replacing it with the new one?
ReplyDeleteYou could be grabbing new images every updateImage call, but not adding them to the page.
There are a number of ways to do it. Something like this would work.
function updateImage()
{
var image = document.getElementById("theText");
if(image.complete) {
var new_image = new Image();
//set up the new image
new_image.id = "theText";
new_image.src = image.src;
// insert new image and remove old
image.parentNode.insertBefore(new_image,image);
image.parentNode.removeChild(image);
}
setTimeout(updateImage, 1000);
}
After getting that working, if there are still problems it is probably a caching issue like the other answers talk about.
As an alternative to...
ReplyDeletenewImage.src = "http://localhost/image.jpg?" + new Date().getTime();
...it seems that...
newImage.src = "http://localhost/image.jpg#" + new Date().getTime();
...is sufficient to fool the browser cache without bypassing any upstream caches, assuming you returned the correct Cache-Control headers. Although you can use...
Cache-Control: no-cache, must-revalidate
...you lose the benefits of the If-Modified-Since or If-None-Match headers, so something like...
Cache-Control: max-age=0, must-revalidate
...should prevent the browser from re-downloading the entire image if it hasn't actually changed. Tested and working on IE, Firefox, and Chrome. Annoyingly it fails on Safari unless you use...
Cache-Control: no-store
...although this still may be preferable to filling upstream caches with hundreds of identical images, particularly when they're running on your own server. ;-)