资源修改后ETag更新疑问:浏览器缓存将采用哪个ETag值?
问题解答
核心结论
默认情况下,浏览器会沿用旧的ETag($eTag1)发起条件请求,不会自动使用PUT返回的新ETag($eTag2)——你的担忧是合理的,PUT和GET请求的缓存状态默认是独立的,PUT操作不会自动同步更新GET请求的缓存条目。
具体流程拆解
- 第一次
GET /myResource后,浏览器会缓存该资源的响应,同时记录关联的ETag($eTag1),缓存键基于请求的URL和GET方法。 - 当发起
PUT /myResource更新资源时,这是一个修改类请求,浏览器不会自动将PUT响应中的新ETag同步到GET请求的缓存条目里——两者属于不同的请求上下文,缓存是相互独立的。 - 再次发起
GET /myResource时,浏览器会带着旧的If-None-Match: $eTag1头发送条件请求:- 服务器对比后发现ETag不匹配,会返回
200 OK和新的资源内容,同时带上新ETag($eTag2); - 浏览器收到响应后,会更新本地缓存中的资源和ETag,后续的GET请求就会使用$eTag2了。
- 服务器对比后发现ETag不匹配,会返回
如何优化缓存同步(避免不必要的条件请求)
如果想让PUT操作后,浏览器直接获取最新资源而不用发条件请求,可以通过服务端配置实现:
- 在PUT响应中设置缓存失效头:返回
Cache-Control: max-age=0, must-revalidate,告知浏览器立即失效对应URL的缓存,下次GET时直接请求最新资源,同时更新缓存。 - 返回重定向:PUT成功后返回
303 See Other状态码,并重定向到GET /myResource,浏览器会自动发起GET请求,获取最新的资源和ETag,同步更新缓存。 - 使用版本化URL:比如将资源URL设计为
/myResource?v=1,更新后改为v=2,从根源上避免缓存冲突,但这需要前端配合修改请求URL。
内容的提问来源于stack exchange,提问作者oleg_zh
相关产品推荐
相关产品推荐

