在我的网络应用程序中,我们使用HTTP缓存标头提供24小时的所有图像,以及ETag。但有时Javascript客户端应用程序有理由怀疑图像可能已更新。在这些情况下,我想强制浏览器重新验证图像缓存,而不会实际破坏缓存。
例如,我获得了一个用户记录(使用JSON),其上有最近的LastUpdated日期。 LastUpdated日期可能有几种可能的原因:用户可能已经更改了昵称,或者加入了新的电路板,或者更改了他们的图像。所以图像很可能没有改变,但我们需要检查。
我知道我可以通过附加到URL的缓存断开器重新请求图像。但是这会强制图像重新加载,无论它是否已经改变,在浏览器的缓存中导致两个条目,并迫使我用新的URL更新我的所有图像。我真正想要的是让浏览器重新请求相同的URL,并在请求中发送正确的If-None-Match和/或If-Modified-Since标头,以便在图像未更改时获得304
有没有办法在Javascript中实现这一点?
答案 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);
}
});
}