在浏览器缓存,代理缓存和原始服务器的情况下,验证如何工作?

时间:2018-06-05 08:30:33

标签: validation browser-cache etag http-caching http-status-code-304

请参阅:https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Freshness

  

当缓存收到过时资源的请求时,它会使用If-None-Match转发此请求以检查它是否实际上仍然是新鲜的。如果是这样,服务器返回304(未修改)标头而不发送所请求资源的主体,从而节省了一些带宽。

假设我们有:浏览​​器缓存,代理缓存和原始服务器:

  • 浏览器缓存包含存储的陈旧资源,其实体标记为“A”。
  • 代理缓存包含存储的陈旧资源,其实体标记为“B”。代理缓存可以充当客户端,也可以充当服务器。

例如,如果您刚刚开始使用代理缓存,则会出现这种情况。在这种情况下会发生什么?

  • 浏览器将使用If-None-Match:“A”发送条件请求。
  • 代理缓存接收条件请求。
  • 代理缓存将转发此请求(根据上面的引用)。这是因为代理缓存中存储的资源是陈旧的。
  • 源服务器接收带有entity-tag“A”的请求。

假设原始服务器上的资源包含实体标记“A”。现在服务器将响应304 Not Modified响应。

此时,我不再理解事情,所以也许我之前误解了一些事情? 304响应对于浏览器缓存是可以的,因为它包含与源服务器上相同的资源(相同的实体标签)。但是,代理缓存包含较旧的资源(具有不同的Etag)。如果代理缓存会收到304响应(并且会更新其元数据),那么代理缓存会使资源再次有效,而它是旧资源。

这是不可取的,所以我可能在某个地方犯了错误?它是如何实际工作的?我怎么看这个过程?

1 个答案:

答案 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响应转发给浏览器。收到后,浏览器可以使用其元数据刷新陈旧响应。