views:

130

answers:

2

Assume a simple aspx data entry page in which admin user can upload an image as well as some other data. They are stored in database and the next time admin visits that page to edit record, image data fetched and a preview generated and saved to disk (using GDI+) and the preview is shown in an image control.

This procedure works fine for the first time however if the image changes (a new one uploaded) the next time the page is surfed it shows previously uploaded image. I debugged the application and everything works correct. The new image data is in database and new preview is stored in Temp location however the page shows previous one. If I refresh the page it shows the new image preview. I should mention that preview is always saved to disk with one name (id of each record as the name).

I think that is because of IE and other browsers use client cache instead of loading images each time a page is surfed. I wonder if there is a way to force the client browser to refresh itself so the newly uploaded image is shown without user intervention.

Thanks and appreciation in advance,

+1  A: 

The easiest way would be to have your application change the file name of the image every time you upload a new image.

Perhaps by appending a date or a date and a time to the end of the image file name.

Or, you can try setting the Cache Control in the HTML header: <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

Gilbert Le Blanc
+1 This approach has worked in the past for me. In particular, when releasing a new version of a site with new images. We included the version number in the url for our images. In your case, you should come up with a means of incrementing a version on an image by image basis. A nice little string parsing exercise for you maybe. One caveat is that any images that are referenced in css stylesheets do not work too well with this approach, but this should not affect you in this case.
Daniel Dyson
Another thing. Be aware that @Gilbert's answer is a two part answer: Change the file name OR set Cache Control. I am advocating the first part, changing the filename, but not the second part, "NO-CACHE" as the latter would mean you lost the benefit of clientside caching when the image is not changed.
Daniel Dyson
A: 

The HTTP Spec contains various headers used to convey information about the "cacheability" of resources to clients. Wikipedia also has a good summary here.

Basically, when a server hands the client some resource, it comes with various metadata. Based on this metadata, the client decides whether or not to cache the resource, and if so, for how long.

You can solve your problem various ways. The easiest way may just be to always set the Expires header on your image response to a value of January 1, 1970 (Unix Epoch). This will tell the client to expire the cache entry in 1970. Since it's always past 1970, the client will never cache the resource and will always request a new copy.

This approach does have its downsides, namely that you needlessly incur extra bandwidth and load on the server if the image never changes. That's where the ETag and LastModified headers come in.

The server can calculate a short hash for every resource. Let's say one image's hash works out to a423fedc. The client will store this hash and when asking for the resource a second time, provide it to the server using the If-None-Match request header. If the server calculates that the ETag for that resource is unchanged, it will just send back a 304 Not Modified and the client can use the cached version. ETags are explained further here.

But I think the best solution in your case is the Last-Modified header. The server will send a date corresponding to the last time an image was modified. Upon reloading the page, the client sends back this same date as part of the If-Modified-Since header. If the image has been modified since that date, the server sends the updated image. If not, it sends back the 304 Not Modified code.

I'm not an ASP developer, so I can't tell you how to set these headers on your response, but if you can figure out how, every web browser will do the caching correctly. I did find this article which looks like it can tell you how to do this in ASP-land, but just knowing about the headers should be enough to get you started.

For debugging, it's a good idea to test with a browser like Firefox using the Firebug plugin. It can show you the headers on your requests and responses, so you know what's actually going over the wire. If you are using a cached version, or if the server isn't returning new data, you'll actually see the 304 response in Firebug, which can be useful.

jasonmp85