Test case:
<script>
console.log('request');
(new Image()).src = 'https://s3.amazonaws.com/mapbox-gl-js/tests/no-cache.png';
setInterval(function() {
console.log('request');
(new Image()).src = 'https://s3.amazonaws.com/mapbox-gl-js/tests/no-cache.png';
}, 5000);
</script>
Neither Chrome nor Firefox make any network requests for no-cache.png
beyond the first, despite it being served with Cache-Control: no-cache
, indicating that user agents must revalidate cached content.
A few questions here (e.g. this one) touch on this and provide workarounds, but I'm most interested in answering more fundamental questions:
- What web specifications, if any, permit or require this behavior?
- If it is not specified, is it at least officially documented by one or more browsers?
- What controls, if any, do web authors have over this behavior?
- In particular, is there a way to bust the cache without losing the benefits of revalidation via
If-None-Match
, as the use of a cache-busting query parameter does?
The special behavior for images is specified in the HTML Standard:
It is this flag that controls whether a user agent removes an entry from the list of available images or not given higher-layer caching semantics for the resource (e.g. the HTTP
Cache-Control
response header).The flag is set and the image added to the list of available images when the networking task to load an image source completes.
According to this comment on a Chromium bug inquiring about this behavior,
Cache-Control: no-store
will override this behavior in Chrome, but this is subject to change.Besides
Cache-Control: no-store
or appending a cache-busting query parameter to the URL, which also disables revalidation viaIf-None-Match
, I know of one other way of bypassing the ignore higher-level caching flag: load the image data viaXMLHttpRequest
, settingxhr.responseType = 'arraybuffer'
, create aBlob
object with the response data, and then load the blob into anImage
withcreateObjectURL
: