I generate some images using a PHP lib.
Sometimes the browser does not load the new generated file.
How can I disable cache just for images created dynamica
I've used this to solve my similar problem ... displaying an image counter (from an external provider). It did not refresh always correctly. And after a random parameter was added, all works fine :)
I've appended a date string to ensure refresh at least every minute.
sample code (PHP):
$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";
That results in a src
link like:
http://xy.somecounter.com/?id=1234567890&1207241014
Browser caching strategies can be controlled by HTTP headers. Remember that they are just a hint, really. Since browsers are terribly inconsistent in this (and any other) field, you'll need several headers to get the desired effect on a range of browsers.
header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
If you need to do it dynamically in the browser using javascript, here is an example...
<img id=graph alt=""
src="http://www.kitco.com/images/live/gold.gif"
/>
<script language="javascript" type="text/javascript">
var d = new Date();
document.getElementById("graph").src =
"http://www.kitco.com/images/live/gold.gif?ver=" +
d.getTime();
</script>
Solution 1 is not great. It does work, but adding hacky random or timestamped query strings to the end of your image files will make the browser re-download and cache every version of every image, every time a page is loaded, regardless of weather the image has changed or not on the server.
Solution 2 is useless. Adding nocache
headers to an image file is not only very difficult to implement, but it's completely impractical because it requires you to predict when it will be needed in advance, the first time you load any image which you think might change at some point in the future.
The absolute best way I've found to solve this is to use ETAGS inside a .htaccess file in your images directory. The following tells Apache to send a unique hash to the browser in the image file headers. This hash only ever changes when time the image file is modified and this change triggers the browser to reload the image the next time it is requested.
<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
A common and simple solution to this problem that feels like a hack but is fairly portable is to add a randomly generated query string to each request for the dynamic image.
So, for example -
<img src="image.png" />
Would become
<img src="image.png?dummy=8484744" />
Or
<img src="image.png?dummy=371662" />
From the point of view of the web-server the same file is accessed, but from the point of view of the browser no caching can be performed.
The random number generation can happen either on the server when serving the page (just make sure the page itself isn't cached...), or on the client (using JavaScript).
You will need to verify whether your web-server can cope with this trick.
I was just looking for a solution to this, and the answers above didn't work in my case (and I have insufficient reputation to comment on them). It turns out that, at least for my use-case and the browser I was using (Chrome on OSX), the only thing that seemed to prevent caching was:
Cache-Control = 'no-store'
For completeness i'm now using all 3 of 'no-cache, no-store, must-revalidate'
So in my case (serving dynamically generated images out of Flask in Python), I had to do the following to hopefully work in as many browsers as possible...
def make_uncached_response(inFile):
response = make_response(inFile)
response.headers['Pragma-Directive'] = 'no-cache'
response.headers['Cache-Directive'] = 'no-cache'
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
return response