I would like to refresh an image on a web page every N seconds. The common way to do this is to add ?t= to the image source:
function refreshImage(){
document.getElementById('img1').src='https://someserver/cam?t='+ new Date();
}
window.setInterval(refreshImage,5000);
However, this can break cache proxies like NGINX or CloudFront. For example, if the cache includes t= in the cache key, then it will keep multiple copies in cache. We can exclude t= from the cache key, and this is resolved, but it still means the browser returns to the network on every request, and browser cache will fill needlessly. And it means the proxy has to be different for images.
I have seen elsewhere that this is supposed to work:
function refreshImage(){
document.getElementById('img1').src='https://someserver/cam#t='+ new Date();
}
window.setInterval(refreshImage,5000);
But in my testing, it does not.
We can instead include Cache-Control:no-store in the image response and do this:
function refreshImage(){
document.getElementById('img1').src='https://someserver/cam';
}
window.setInterval(refreshImage,5000);
However, this then breaks proxy caches, telling them not to store the image at all.
I would rather do this in a way that is friendly both to proxy caches and the browser cache. In my mind it would be best to serve the image with, say, Cache-Control:max-age=30, and have it cached for 30s in both browser and proxy caches. The browser shouldn't have to tack on a timestamp, and shouldn't ask again for 30s, and if another browser does, the proxy cache should serve it's copy for 30s. Origin should only see one request every 30s.
I understand I should probably just do ?t= and be done with it, but am trying to understand better why it's this way, and if there is some better way. Am I misunderstanding what should be happening here? Is there some way to make browsers honor Cache-control:max-age=30 for image requests? Some cache header I'm missing?