Caching 强制浏览器刷新缓存的、已标记的图像
在我的网站上,用户生成的图像通过如下方式提供给它们一个Caching 强制浏览器刷新缓存的、已标记的图像,caching,browser,http-headers,Caching,Browser,Http Headers,在我的网站上,用户生成的图像通过如下方式提供给它们一个src: userImage.ashx?id={UserId}&type=avatar 在来自ashx文件的响应中,我设置了etag头。当用户上载新图像时,etag会发生更改 如果浏览器缓存了一个带有etag的文件,则无论何时需要显示该文件,它都应向服务器发送请求,并将If None Match头设置为该etag。如果缓存的etag与服务器上的当前etag相同,服务器将以未修改-304响应。如果etag不同,服务器将响应OK-200
src
:
userImage.ashx?id={UserId}&type=avatar
在来自ashx
文件的响应中,我设置了etag头。当用户上载新图像时,etag会发生更改
如果浏览器缓存了一个带有etag的文件,则无论何时需要显示该文件,它都应向服务器发送请求,并将If None Match
头设置为该etag。如果缓存的etag与服务器上的当前etag相同,服务器将以未修改-304
响应。如果etag不同,服务器将响应OK-200
,并开始发送新文件
从理论上讲,它应该是这样工作的。然而,我发现对于某些浏览器(firefox和IE,未在其他浏览器上测试过),情况并非如此。如果用户导航到一个带有缓存、标记图像的新页面,这些浏览器只需从缓存中使用图像,而无需发出请求。如果用户随后刷新页面,浏览器将发送一个请求,请求中设置了如果没有匹配的标题
所以我的问题是:用户更新他们的一个图像,然后导航到显示该图像的页面。在用户按下刷新按钮之前,将显示缓存的图像,即使它与新图像具有不同的etag。当用户按下refresh时,浏览器会使用If None Match
标题集发出请求,从而触发服务器发送新图像
有可能解决这个问题吗
示例200响应头:
Status=OK - 200
Date=Thu, 27 Oct 2011 14:37:31 GMT
Server=Microsoft-IIS/6.0
X-Powered-By=ASP.NET
X-AspNet-Version=4.0.30319
Transfer-Encoding=chunked
Cache-Control=public, max-age=86400
Etag="27/10/2011 13:23:30"
Content-Type=image/jpg
示例304标头:
Status=Not Modified - 304
Connection=close
Date=Thu, 27 Oct 2011 14:39:12 GMT
Server=Microsoft-IIS/6.0
X-Powered-By=ASP.NET
X-AspNet-Version=4.0.30319
Cache-Control=public, max-age=86400
(使用上次修改的日期作为etag,因为它更适合以后的压缩等需要)IIRC您可以通过“Expires”标题设置文件的有效期。因此,如果您说“此文件在未来两天内有效”,浏览器没有理由联系您的服务器
您的示例中给出的最大年龄基本上做了相同的事情。我解决了这个问题,如下所示:
让服务器端服务始终重定向(暂时移动302)到要显示的映像,并在用户端将映像源重置为重定向+“?”+时间戳
这将强制浏览器再次查询图像,但允许缓存工作
例如,您的用户端javascript请求/redirectme/avatar xxx.jpg?121341
,它将302
发送到/avatar/avatar xxx.jpg
,然后通过Etag缓存正常请求。您需要支付两次往返,以换取不必每次发送整个图像
在Chrome19(不需要时间戳查询字符串)和Firefox10(需要时间戳)中测试。我已经包括了一些标题。我的目标是缓存图像,直到它们需要更新。我认为这就是etags的目的。FRom:“当缓存响应中存在max age cache control指令时,如果响应的当前时间大于新请求该资源时给定的时间值(以秒为单位),则该响应将过时。”当文件是新的,即不过时时,“正确的缓存必须响应”。哦,我明白了,这个想法是没有最大年龄或类似的。但将缓存控制权留给公众。不确定;我认为cache control public仍然允许浏览器缓存文件。我想你需要的是重新验证。另请参见此问题:缓存控制公共意味着主机和浏览器之间的代理可以缓存数据。缓存控制专用于您不希望中间任何人持有的信息。无论如何,它与缓存失效无关。