请参阅:https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Freshness
当缓存收到过时资源的请求时,它会使用If-None-Match转发此请求以检查它是否实际上仍然是新鲜的。如果是这样,服务器返回304(未修改)标头而不发送所请求资源的主体,从而节省了一些带宽。
假设我们有:浏览器缓存,代理缓存和原始服务器:
例如,如果您刚刚开始使用代理缓存,则会出现这种情况。在这种情况下会发生什么?
假设原始服务器上的资源包含实体标记“A”。现在服务器将响应304 Not Modified响应。
此时,我不再理解事情,所以也许我之前误解了一些事情? 304响应对于浏览器缓存是可以的,因为它包含与源服务器上相同的资源(相同的实体标签)。但是,代理缓存包含较旧的资源(具有不同的Etag)。如果代理缓存会收到304响应(并且会更新其元数据),那么代理缓存会使资源再次有效,而它是旧资源。
这是不可取的,所以我可能在某个地方犯了错误?它是如何实际工作的?我怎么看这个过程?
答案 0 :(得分:0)
查看RFC7234规范的section 4.3。第4.3.2节特别说明如下:
当缓存决定重新验证其自己存储的响应时 请求包含实体标记的If-None-Match列表,缓存 可以将收到的列表与自己的实体标签列表组合在一起 存储的响应集(新鲜的或陈旧的)并发送的联合 两个列表作为替换的If-None-Match头字段值 转发请求。如果存储的响应仅包含部分 内容,缓存不得在联合中包含其实体标记 除非请求是针对完全满足的范围 部分存储的响应。如果响应转发 请求是304(未修改)并且具有ETag标头字段值 一个不在客户端列表中的实体标签,缓存必须 通过重用它为客户端生成200(OK)响应 相应的存储响应,由304响应更新 元数据(第4.3.4节)。
因此代理可以将实体标签(A和B)发送到源服务器进行验证。如果资源表示未更改,则源服务器将发送304
响应。如果该响应中的实体标记为B
,则代理可以刷新其陈旧的存储响应,并使用它向客户端发送200 OK
响应。收到此新响应后,浏览器可以使用它更新其缓存。
现在,在您指定的方案中,304 NOT MODIFIED
响应包含实体标记A
(假设您通过代理访问资源,是否会出现这种情况?)。规范似乎没有明确地解决这个特定情况,但我想你可以将304 NOT MODIFIED
响应转发给浏览器。收到后,浏览器可以使用其元数据刷新陈旧响应。