繁体   English   中英

导致浏览器重新验证(但不一定要重新获取)图像

[英]Cause browser to revalidate (but not necessarily refetch) an image

在我的网络应用程序中,我们使用HTTP缓存标头提供24小时的所有图像,以及ETag。 但有时Javascript客户端应用程序有理由怀疑图像可能已更新。 在这些情况下,我想强制浏览器重新验证图像缓存,而不是实际破坏缓存。

例如,我得到一个用户记录(在JSON中),其上有一个最近的LastUpdated日期。 LastUpdated日期可能有几种可能的原因:用户可能已经更改了昵称,或者加入了新的电路板,或者更改了他们的图像。 所以图像很可能没有改变,但我们需要检查。

我知道我可以通过附加到URL的缓存断开器重新请求图像。 但是这会强制图像重新加载,无论它是否已经改变,在浏览器的缓存中导致两个条目,并迫使我用新的URL更新我的所有图像。 我真正想要的是让浏览器重新请求相同的URL,并在请求中发送正确的If-None-Match和/或If-Modified-Since标头,以便在图像未更改时获得304 。

有没有办法在Javascript中实现这一点?

由于映像位于服务器上,因此在缓存中,服务器是查询需要发生的位置。 我会在页面加载之前进行检查,强制服务器在需要时更新缓存中的特定图像。 “HTML”部分应始终假设所有img-tags等都是正确的。

更新服务器缓存中单个文件的最佳方法是另一种野兽IMO。

这实际上很容易实现。 Cache-Control标头设置为max-age=0的图像发出AJAX请求。

服务器必须使用更新的映像(和一组新的缓存头)或304 包含Cache-Control标头(public, max-age=123 )进行响应。

具有Cache-Control标头的304非常重要,因为它指示浏览器更新与资源相关联的新鲜度信息。

请求完成后,从DOM中删除旧的<img>元素,然后重新插入指向同一src的新元素。

这是有效的,因为请求 Cache-Control标头告诉浏览器忽略其缓存并转到网络。 当浏览器获得响应时,它会更新其缓存 - 即使您实际上没有对AJAX结果执行任何操作。

现在,当您删除旧元素并插入新元素时,浏览器会直接从其缓存中获取最近更新的图像。

在Chrome的网络检查器中,您会看到两个请求:AJAX请求,然后通过重新插入<img>元素生成请求。 但是,如果服务器已正确设置Cache-Control标头,则浏览器的缓存将满足第二个“请求”,并且实际上不会通过网络发送任何内容。

function updateImage(el) {
    el = $(el);
    var src = el.attr('src');

    $.ajax({
        url: src,
        headers: {
            'Cache-Control': 'max-age=0'
        },
        success: function() {
            var parent = el.parent(); 
            el.remove();
            // this assumes that the <img> has no siblings and no attributes/classes/etc...
            parent.append('<img>').attr('src',src);
        }
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM