HTTP:结合过期和验证缓存

时间:2011-06-14 21:27:24

标签: http caching conditional http-caching

我遇到以下情况时无法制定HTTP缓存标头。

我们的服务器拥有大量数据,每周可能会更改几次。我希望浏览器缓存这些数据。此外,由于网络不可靠,我希望最大限度地减少条件获取的延迟。

我追求的最终行为是:

  1. 客户请求以前从未见过的资源。
  2. 服务器响应资源以及ETag和max-age(24小时)。
  3. 直到24小时过去,客户端才会使用缓存资源。
  4. 在到期日期之后,客户端将执行验证请求(If-None-Match: [etag]
  5. 如果资源未更改:
    • 服务器以304 Not Modified
    • 回复
    • 以某种方式告知客户现有资源从现在起24小时内有新的到期日期
    • 返回第3步
  6. 归结为它的本能... 304响应是否包含新的max-age?或者原始max-age是否符合后续请求?

1 个答案:

答案 0 :(得分:29)

是的,304响应可以包含新的max-age(或ETag,或其他响应头)。

我使用Firefox 4进行了一项实验,测试原始的max-age或新版本是否得到尊重,答案是新的max-age得到尊重,所以你应该能够实现你想要的要做。

重要的是要记住max-age相对于Date响应标头,而不是Last-Modified,所以每当您的服务器设置24小时的max-age指令时,它都是说“从现在开始24小时。”因此,假设这是您想要的,您根本不必更改max-age,只需返回86400。

无论如何,这是我的实验的概述和转储。基本上,我点击了设置ETag的测试URL并将max-age设置为120秒。因此,服务器返回带有这些响应头的页面:

HTTP/1.1 200 OK
Date: Tue, 14 Jun 2011 23:48:51 GMT
Cache-Control: max-age=120
Etag: "901ea3d0ac9303ae4855a09676f96701"
Last-Modified: Mon, 13 Jun 2011 22:20:03 GMT

然后我重复点击地址栏中的“输入”来加载页面(但不强制重新加载)。没有网络流量,因为Firefox反复从缓存重新加载页面。然后,在120秒结束后,当我下次进入时,Firefox会向服务器发送一个条件GET,正如您所期望的那样。来自服务器的请求和响应是:

GET /example HTTP/1.1
If-Modified-Since: Mon, 13 Jun 2011 22:20:03 GMT
If-None-Match: "901ea3d0ac9303ae4855a09676f96701"

HTTP/1.1 304 Not Modified
Date: Tue, 14 Jun 2011 23:50:54 GMT
Etag: "901ea3d0ac9303ae4855a09676f96701"
Cache-Control: max-age=240

请注意,在304响应中,我已将服务器更改max-age从120秒更改为240.

所以,最重要的问题是,120秒后会发生什么? Firefox会尊重新的max-age并继续从缓存中加载页面,还是会点击服务器?答案是它继续从缓存加载页面,直到达到240秒后才重新请求:

GET /example HTTP/1.1
If-Modified-Since: Mon, 13 Jun 2011 22:20:03 GMT
If-None-Match: "901ea3d0ac9303ae4855a09676f96701"

HTTP/1.1 304 Not Modified
Date: Tue, 14 Jun 2011 23:54:56 GMT
Etag: "901ea3d0ac9303ae4855a09676f96701"
Cache-Control: max-age=240

我重复了另一个240秒的循环,事情按照你的预期运作。所以,希望能为你解答这个问题。

RFC解释了应该如何实现年龄计算,以及其他Cache-Control参数如何工作。不能保证每个浏览器和代理都遵循这些规则,但此时HTTP 1.1已经很老了,你会发现它们中的大多数都会像Firefox一样。

注意:为了简化这些示例转储,我删除了无关的标头,例如主机,连接/保持活动,内容编码/长度/类型,用户代理等。)< / p>