views:

2404

answers:

5

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 back ground and then update the one on the page I only get the same image.

If i refresh the entire page then the image is updated.

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?

+6  A: 

Try adding a cachebreaker at the end of the url:

newImage.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.

Paolo Bergantino
Yep, this is the answer. But it is still a shame that the browser doesn't respect the headers.
Josh Stodola
A: 

Try using a worthless querystring to make it a unique url:

function 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);
}
Joel Potter
Added the WQS to the code and verified that the request is being accepted and that the browser sees the response as coming from the address + WQS with out the image refreshing.
JustSmith
A: 

One answer is to hackishly add some get query parameter like has been suggested.

A 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.

Edward Kmett
This sounded like it would have worked but it still shows the same image, even with the hacks. I will add the header information to the question.
JustSmith
I just noticed that you are refreshing the same img tag over and over. The browser is probably detecting when you go to set the src that the src hasn't changed, and so its not bothering to refresh. (Since this check is happening at the DOM level and has nothing to do with the target). What happens if you add "?" + number -- to the url of the image being retrieved?
Edward Kmett
A: 

After creating the new image, are you removing the old image from the DOM and replacing it with the new one?

You 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.

BaroqueBobcat
A: 

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.

E.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);
}
JustSmith