2015-05-21 62 views
3

我读过很多关于这个问题相关的文章,也对HTTP缓存在这里很好的文章: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en#invalidating-and-updating-cached-responses 但它仍然不是很清楚,我:为什么ETag不足以使浏览器缓存无效?

为什么不发送ETag头足使特定资源的浏览器缓存无效?为什么每个人都建议实际更改资源的URL /文件名以强制浏览器重新下载文件?如果浏览器已经使用特定的ETag对文件进行了缓存,并且在服务器上修改了ETag,那会不够吗?

回答

1

我发现下面的页面有所帮助:

这条线从MDN的ETag的页面股的关键点(强调):

如果用户再次访问给定的URL(它带有一个ETag集),并且它是陈旧的,这太旧而不能被视为可用,客户端会将它的ETag的值发送到If-None-Match头域...

ETag将被客户端用来重新验证资源,一旦它们变成“陈旧”。但什么构成“陈旧”?

这是Cache-Control标头派上用场的地方。 Cache-Control头可以与响应一起发送,让客户知道客户端可以缓存一个项目多长时间,直到它被认为是陈旧的。例如,Cache-Control: no-cache将表明该资源应被视为立即失效。有关可用缓存控制值的更多信息,请参阅MDN Cache-Control page

当浏览器试图处理该被视为失效一个缓存的资源的请求时,它将首先发送一个重新验证请求发送到与所述资源的最后一个ETag值经由If-None-Match请求头包括服务器,如上MDN's ETag page说明。它也可以使用作为If-Modified-Since请求标头发送的Last-Modified响应标头作为辅助选项。

如果服务器确定客户机的ETag值(在If-None-Match请求头)是当前的,那么它将用304(未修改)HTTP状态代码和一个空的本体响应,表示该客户端可以使用高速缓存的条目。否则,服务器将以200 HTTP状态码和新的响应主体进行响应。

其他资源:

直接回答你的问题:

  • 为什么不发送ETag头,足以无效浏览器缓存特定资源? - 因为ETag标头在被认为已过期之前未经过验证,例如通过在Cache-Control响应标头中设置的到期日期。
  • 为什么大家都推荐实际更改资源的URL /文件名以强制浏览器重新下载文件? - 更改URL /文件名或添加查询字符串将强制客户端避免使用缓存。这很简单,并且实际上保证了缓存清除的方式。这并不意味着它是必要的,但它在浏览器行为不一致的领域往往是安全的。
  • 如果浏览器已经使用特定的ETag对文件进行了缓存,并且在服务器上修改了ETag,那不就够了吗? - 从技术上讲,只要包含适当的Cache-Control标题(包括PragmaExpires标题)就足够了。有关更多详细信息,请参阅How to control web page caching, across all browsers?
+0

谢谢你的详细解答。尽管从技术的角度来看,如果所有的浏览器,服务器和代理在实现上都是一致的,我仍然没有理由认为ETag本身不足以满足所有缓存目的。 因此,除非我错了,否则我的问题的简单答案是由于不同实现中的不一致。 – AsGoodAsItGets

+0

另外,对于我来说,*陈旧*的概念是不必要的。浏览器可以保留文件的缓存版本,直到它耗尽分配的缓存空间,并且需要为新文件释放一些空间,或者在服务器上更改该特定文件的ETag。我不明白为什么我们需要引入* stale *的概念。 – AsGoodAsItGets

+1

对不起,我的回答可能并不清楚资源是否“陈旧”。如果资源是“过期的”,客户端将*仅*验证缓存资源的ETag(或最后修改日期)。所以即使服务器的资源发生变化,客户端也不会真正检查这个变化,直到满足这个“陈旧”的要求。它将继续使用本地缓存,并不会向服务器发送任何请求。在这个意义上,“陈旧”的概念非常重要,因为它决定了缓存资源的最大“过时”性。 –