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

时间:2012-04-20 15:18:45

标签: javascript html

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

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

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

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

这实际上很容易实现。对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);
        }
    });
}