为什么浏览器不尊重Cache-Control标头来加载`(new Image())。src = ...`的图像? [英] Why don't browsers respect Cache-Control headers for images loaded with `(new Image()).src = ...`?

查看:111
本文介绍了为什么浏览器不尊重Cache-Control标头来加载`(new Image())。src = ...`的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

测试用例:

<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>

Chrome和Firefox都不会对 no-cache.png ,尽管已与 Cache-Control:no-cache 一起使用,表示用户代理必须重新验证缓存内容。

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:


  • 哪些网络规范(如果有的话)允许或要求这种行为?

  • 如果未指定,至少由一个或多个浏览器正式记录?

  • 网络作者对此行为有什么控制措施?

  • 尤其是,有没有办法破坏缓存而不会丢失通过 If-None-Match 重新验证的好处,就像使用缓存无效化查询参数一样?

  • 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?

推荐答案

图像的特殊行为在 HTML标准


每个 Document 对象必须具有可用图像列表。此列表中的每个图像都由一个元组标识,该元组包含绝对URL,CORS设置属性模式,以及如果该模式不是No CORS,则为原点。每个图像还有一个忽略高层缓存标志

Each Document object must have a list of available images. Each image in this list is identified by a tuple consisting of an absolute URL, a CORS settings attribute mode, and, if the mode is not No CORS, an origin. Each image furthermore has an ignore higher-layer caching flag.

此标志控制是否用户代理从可用图像列表中删除一个条目,或者从资源的高层缓存语义未指定的条目中删除该条目(例如HTTP Cache-Control 响应标头)。

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.

根据此评论在询问此行为的Chromium错误中, Cache-Control:无存储将在Chrome中覆盖此行为,但这可能会更改。

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.

除了 Cache-Control:no-store 或在URL上附加一个缓存无效查询参数,这也会通过<$ c禁用重新验证$ c> If-None-Match ,我知道b的另一种方式跳过忽略高级缓存标志:通过 XMLHttpRequest 设置 xhr.responseType ='arraybuffer'加载图像数据,使用响应数据创建一个 Blob 对象,然后将该Blob加载到具有 Image > createObjectURL :

Besides Cache-Control: no-store or appending a cache-busting query parameter to the URL, which also disables revalidation via If-None-Match, I know of one other way of bypassing the ignore higher-level caching flag: load the image data via XMLHttpRequest, setting xhr.responseType = 'arraybuffer', create a Blob object with the response data, and then load the blob into an Image with createObjectURL:

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
    var img = new Image();
    img.onload = function() {
        // ... do something with img
        URL.revokeObjectURL(img.src);
    };
    var blob = new Blob([new Uint8Array(xhr.response)], { type: 'image/png' });
    img.src = URL.createObjectURL(blob);
};
xhr.send();

这篇关于为什么浏览器不尊重Cache-Control标头来加载`(new Image())。src = ...`的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆