延迟加载背景图像时防止双重请求

Prevent double request when lazy loading a background-image

本文关键字:请求 背景 图像 延迟加载      更新时间:2023-09-26

我正在尝试使用Javascript并在下载完成后使用回调来延迟加载背景图像。我正在使用这个代码

var img = new Image();
img.onload = function() {
    element.style.backgroundImage = 'url(' + this.src + ')';
    // Need to do other things here
}
img.src = 'path_to_image.jpg';

它在Chrome、Firefox和IE 9+上运行良好,但在使用Safari(OSX和iOS)或Android浏览器时,它会向服务器发出两个请求。这两个浏览器似乎不使用缓存。你知道如何做到这一点而不需要下载两次每个图像吗?

如果它有帮助,我不需要它与IE 10和更早的兼容

我通过在传输图像文件时设置缓存控制头来解决这个问题。显然,如果您不另行指定,Safari会认为图像会立即过期,因此它们会在预加载和首次使用之间过期。

您可能需要使用Web服务器指令来更改这些标头,正如我在找到问题的一般解决方案时所建议的那样(jQuery Pre-load Not Caching in Chrome或Safari)。在Apache上启用一天缓存应该是这样的:

<FilesMatch "'.(gif|jpeg|jpg|png|svg)$">
    Header set Cache-Control "public, max-age=86400"
</FilesMatch>

在我快速尝试验证它时,这实际上并不起作用,但Apache 2.4文档中的例子也不起作用,所以我可能还有其他事情要做

在我的例子中,我碰巧在控制器中生成原始图像,所以在返回它们之前,我最终使用我的应用程序框架(CakePHP 3)的一个功能设置了标题:

$this->response->cache('-10 seconds', '+40 seconds');

这导致Cake在响应中添加了三个标题:

Last-Modified:   Fri, 24 Jun 2016 10:20:14 GMT
Expires:         Fri, 24 Jun 2016 10:21:04 GMT
Cache-Control:   public, max-age=40

这让我担心客户端和服务器之间的时钟差异,但根据HTTP/1.1规范:

如果响应同时包含Expires标头和最大年龄指令,则最大年龄指令将覆盖Expires标题,即使Expires头的限制性更强。