5

I'm storing and caching images with link like this

http://example.com/1.jpg
http://example.com/2.jpg

Users have ability to modify and overwrite 1.jpg or 2.jpg. So what I want to cache all images but update the cache of that image file which is just over-written. Right now I'm using .htaccess method for cache

<IfModule mod_expires.c>
ExpiresActive On
<FilesMatch "(?i)^.*\.(jpg|jpeg|png)$">
ExpiresDefault "access plus 1 year"
</FilesMatch>
</IfModule> 

But using this method image still remains the same even if user overwrites the file.

Nat Ritmeyer
  • 5,634
  • 8
  • 45
  • 58
Basic Bridge
  • 1,881
  • 4
  • 25
  • 37
  • 3
    Use the `ETag` header for a [conditional request](https://en.wikipedia.org/wiki/HTTP_ETag). –  Nov 11 '12 at 18:08
  • How are users accessing these images? Via a HTML page with `` tags? How is the HTML page generated? – vladr Nov 17 '12 at 06:13
  • @user647772 - Please post your suggestion as an answer, and I'll grant the bounty; unless someone comes up with a better answer by tomorrow. – WEFX Nov 20 '12 at 13:34

2 Answers2

5

Going forward, ETags should serve your needs with no further effort. ETags should work by default so you don't really need to do anything, but to avoid problems in multiple-server environments you can configure your ETags to be calculated from the file size and last-modified timestamp. For example, replace your existing directives with the following line in your .htaccess or Apache configuration:

FileETag MTime Size

The ETag will effectively "expire" the cached image automatically when the image changes. The downside is that the browser still inquires about the resource with each request so it's a little less efficient than the expiration directives you used. On the other hand ETags avoid the problem you've described.

However, if you've already used one of the cache directives as described in your question and set the Expires value to something far in the future, then any browser that requested the file in the past won't check it again for some time. You can hack around that by appending a trivial query string like ?cache=123 to the URL just to make it different (thus bypassing the cache). Then you can rely on the ETag mechanism in future.

DMI
  • 6,843
  • 2
  • 24
  • 25
Magnus
  • 10,736
  • 5
  • 44
  • 57
2

The problem is likely not on the server, but the browser. Browsers don't check the server for changes to images. What you did doesn't quite address that issue.

The following will tell the browser to always check the server for changes.

<IfModule mod_headers.c>
  <FilesMatch "(?i)^.*\.(jpg|jpeg|png)$">
  Header set Cache-Control "max-age=0"
  </FilesMatch>
</IfModule>

Just be aware this will make your site slower when accessing these images. The files will still be cached, but the browser will check the server to see if they have changed (If-Modifed-Since). Increase max-age (in seconds) to increase performance at the expense of staleness.

(BTW, "max-age=0, must-revalidate" is a better value, but browsers have misimplemented the spec. must-revalidate may disable cache in some browsers and proxies.)

See also https://stackoverflow.com/a/1383359/1205867

Community
  • 1
  • 1
mikeslattery
  • 4,039
  • 1
  • 19
  • 14