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

时间:2016-04-30 01:50:56

标签: javascript javascript-events background-image lazy-loading

我正在尝试使用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及更旧版本兼容

1 个答案:

答案 0 :(得分:0)

我通过在传输图像文件时设置Cache-Control标头来解决这个问题。如果您没有另外指定,Safari会认为图像会立即过期,因此它们会在预加载和首次使用之间过期。

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

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

这对我来说实际上并不能快速验证它,但the example in the Apache 2.4 docs也没有,所以我可能还有其他事情要发生。

在我的情况下,我碰巧在控制器中生成原始图像,所以在我返回之前,我最终使用应用程序框架(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

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

  

如果响应同时包含Expires标头和max-age指令,则max-age指令会覆盖Expires标头,即使Expires标头限制性更强。