views:

2174

answers:

11

I know there are many ways to prevent image caching (such as via META tags), as well as a few nice tricks to ensure that the current version of an image is shown with every page load (such as image.jpg?x=timestamp), but is there any way to actually clear or replace an image in the browsers cache so that neither of the methods above are necessary?

As an example, lets say there are 100 images on a page and that these images are named "01.jpg", "02.jpg", "03.jpg", etc. If image "42.jpg" is replaced, is there any way to replace it in the cache so that "42.jpg" will automatically display the new image on successive page loads? I can't use the META tag method, because I need everuthing that ISN"T replaced to remain cached, and I can't use the timestamp method, because I don't want ALL of the images to be reloaded every time the page loads.

I've racked my brain and scoured the Internet for a way to do this (preferrably via javascript), but no luck. Any suggestions?

JOSH

A: 

The reason the ?x=timestamp trick is used is because that's the only way to do it on a per image basis. That or dynamically generate image names and point to an application that outputs the image.

I suggest you figure out, server side, if the image has been changed/updated, and if so then output your tag with the ?x=timestamp trick to force the new image.

TravisO
+4  A: 

If you're writing the page dynamically, you can add the last-modified timestamp to the URL:

<img src="image.jpg?lastmod=12345678" ...

Greg
+4  A: 

<meta> is absolutely irrelevant. In fact, you shouldn't use it at all for controlling cache (by the time anything reads content of document, it's already cached).

In HTTP each URL is independent. Whatever you do to the HTML document, it won't apply to images.

To prevent caching you should either change URLs each time (if you update images from time to time, allow them to be cached forever and use new filename for new image – it's the best solution for long-lived files).

If your image changes very often (every few minutes, or even on each request), then send Cache-control: no-cache or Cache-control: max-age=xx where xx is number of seconds that image is "fresh".

Random URL for short-lived files is bad idea – it pollutes cache with useless files and forces useful files to be purged.

If you have Apache and mod_headers or mod_expires then create .htaccess file with appropriate rules.

<Files ~ "-nocache\.jpg">
   Header set Cache-control "no-cache"
</Files>

Above will make *-nocache.jpg files non-cacheable.

You could also serve images via PHP script (they have awful cachability by default :)

porneL
A: 

Change the ETAG for the image.

StingyJack
It won't help if browser doesn't validate cached image.
porneL
with browser caching, there is never a one-solution fits all. this is just one to add to the few you suggested.
StingyJack
+3  A: 

I'm sure most browsers respect the Last-Modified HTTP header. Send those out and request a new image. It will be cached by the browser if the Last-Modified line doesn't change.

strager
A: 

Thanks for the responses so far! Although I appreciate it, most of you guys ignored the problem posed by my question, which is that I CANNOT use the META tag method OR the timestamp method, because I want all of the images cached under normal circumstances.

In the event that an image is re-uploaded, is there a way to CLEAR or REPLACE the previously cached image client-side? In my example above, the goal is to make the browser forget what "42.jpg" is and reload ONLY that image (loading the rest from cache). Is this even possible? Thanks again for weighing in!

JOSH

You are misunderstanding most of our posts. Re-read them; they involve editing the HTTP responses of the images. I don't think it is possible to juggle the browser's cache in Javascript, either. Also, edit your original post and don't post an answer which isn't an answer.
strager
A: 

In the event that an image is re-uploaded, is there a way to CLEAR or REPLACE the previously cached image client-side? In my example above, the goal is to make the browser forget what "42.jpg" is

You're running firefox right?

  • Find the Tools Menu
  • Select Clear Private Data
  • Untick all the checkboxes except make sure Cache is Checked
  • Press OK

:-)

In all seriousness, I've never heard of such a thing existing, and I doubt there is an API for it. I can't imagine it'd be a good idea on part of browser developers to let you go poking around in their cache, and there's no motivation that I can see for them to ever implement such a feature.

I CANNOT use the META tag method OR the timestamp method, because I want all of the images cached under normal circumstances.

Why can't you use a timestamp (or etag, which amounts to the same thing)? Remember you should be using the timestamp of the image file itself, not just Time.Now.
I hate to be the bearer of bad news, but you don't have any other options.

If the images don't change, neither will the timestamp, so everything will be cached "under normal circumstances". If the images do change, they'll get a new timestamp (which they'll need to for caching reasons), but then that timestamp will remain valid forever until someone replaces the image again.

Orion Edwards
A: 

@Orion:

Clearing my own browser cache isn't the issue (is it ever?) I'm trying to make this work for my website visitors, and you never ask them to clear their cache manually.

I can't use the timestamp method, because that will only add a new image to the cache (such as "42.jpg?x=123456"). Any successive calls to "42.jpg" on the same page or other pages will still display the OLD cached image.

I've considered storing each image's timestamp in a MySQL database, but that would mean having to query the database for the current timestamp every single time each image is loaded. That's a ton of queries and can't be good for performance!

Is there no way to clear or overwrite an individual file in the cache? Maybe force a silent reload of the image in the background somehow?

JOSH

A: 

No, there is no way to force a file in a browser cache to be deleted, either by the web server or by anything that you can put into the files it sends. The browser cache is owned by the browser, and controlled by the user.

Hence, you should treat each file and each URL as a precious resource that should be managed carefully.

Therefore, porneL's suggestion of versioning the image files seems to be the best long-term answer. The ETAG is used under normal circumstances, but maybe your efforts have nullified it? Try changing the ETAG, as suggested.

Rob Williams
A: 

When changing the image filename is not an option then use a server side session variable and a javascript window.location.reload() function. As follows:

After Upload Complete: Session("reload") = "yes"

On page_load: If Session("reload") = "yes" Then Session("reload") = Nothing ClientScript.RegisterStartupScript(Me.GetType), "ReloadImages", "window.location.reload();", True) End If

This allows the client browser to refresh only once because the session variable is reset after one occurance.

Hope this helps.

Pete