ChatGPT解决这个技术问题 Extra ChatGPT

Refresh image with a new one at the same url

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?

One decade later, and we still need to achieve this in hack-ish way. Can't browser makers provide : img.reload()?
fetch is a better solution in 2022! See stackoverflow.com/a/66312176/5535820

P
Paolo Bergantino

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.


Not a very good solution as it will swamp caches (both local and upstream). Aya's answer has a better way of dealing with this.
Also, re-displaying the same image elsewhere, without the "cache breaker" later, still shows the old cached version (at least in firefox) both ? and # :(
You can make even less code with this: 'image.jpg?' + (+new Date())
There is Date.now() for this
Why not Math.random()
D
Doin

I've seen a lot of variation in answers for how to do this, so I thought I'd summarize them here (plus add a 4th method of my own invention):

(1) Add a unique cache-busting query parameter to the URL, such as:

newImage.src = "image.jpg?t=" + new Date().getTime();

Pros: 100% reliable, quick & easy to understand and implement.

Cons: Bypasses caching altogether, meaning unnecessary delays and bandwidth use whenever the image doesn't change between views. Will potentially fill browser cache (and any intermediate caches) with many, many copies of exactly the same image! Also, requires modifying image URL.

When to use: Use when image is constantly changing, such as for a live webcam feed. If you use this method, make sure to serve the images themselves with Cache-control: no-cache HTTP headers!!! (Often this can be set up using a .htaccess file). Otherwise you'll be progressively filling caches up with old versions of the image!

(2) Add query parameter to the URL that changes only when the file does, e.g.:

echo '<img src="image.jpg?m=' . filemtime('image.jpg') . '">';

(That's PHP server-side code, but the important point here is just that a ?m=[file last-modified time] querystring is appended to the filename).

Pros: 100% reliable, quick & easy to understand and implement, and preserves caching advantages perfectly.

Cons: Requires modifying the image URL. Also, a little more work for the server - it has to get access to the file-last-modified time. Also, requires server-side information, so not suitable for a purely client-side-only solution to check for a refreshed image.

When to use: When you want to cache images, but may need to update them at the server end from time to time without changing the filename itself. AND when you can easily ensure that the correct querystring is added to every image instance in your HTML.

(3) Serve your images with the header Cache-control: max-age=0, must-revalidate, and add a unique memcache-busting fragment identifier to the URL, such as:

newImage.src = "image.jpg#" + new Date().getTime();

The idea here is that the cache-control header puts images in the browser cache, but immediately markes them stale, so that and every time they are re-displayed the browser must check with the server to see if they've changed. This ensures that the browser's HTTP cache always returns the latest copy of the image. However, browsers will often re-use an in-memory copy of an image if they have one, and not even check their HTTP cache in that case. To prevent this, a fragment identifier is used: Comparison of in-memory image src's includes the fragment identifier, but it gets stripped of before querying the HTTP cache. (So, e.g., image.jpg#A and image.jpg#B might both be displayed from the image.jpg entry in the browser's HTTP cache, but image.jpg#B would never be displayed using in-memory retained image data from when image.jpg#A was last displayed).

Pros: Makes proper use of HTTP caching mechanisms, and uses cached images if they haven't changed. Works for servers that choke on a querystring added to a static image URL (since servers never see fragment identifiers - they're for the browsers' own use only).

Cons: Relies on somewhat dubious (or at least poorly documented) behaviour of browsers, in regard to images with fragment identifiers in their URLs (However, I've tested this successfully in FF27, Chrome33, and IE11). Does still send a revalidation request to the server for every image view, which may be overkill if images only change rarely and/or latency is a big issue (since you need to wait for the revalidation response even when the cached image is still good). Requires modifying image URLs.

When to use: Use when images may change frequently, or need to be refreshed intermittently by the client without server-side script involvement, but where you still want the advantage of caching. For example, polling a live webcam that updates an image irregularly every few minutes. Alternatively, use instead of (1) or (2) if your server doesn't allow querystrings on static image URLs.

[EDIT 2021: No longer works on recent Chrome & Edge: The internal memcache in those browsers now ignores fragment identifiers (maybe since the switch to the Blink engine?). But see method (4) below, it's now MUCH easier on those two browsers specifically, so consider combining this method with a simplified version of (4) to cover those two browsers].

(4) Forcibly refresh a particular image using Javascript, by first loading it into a hidden