是的,304 响应可以包含一个新的max-age
(或 ETag 或其他响应标头)。
我用Firefox 4做了一个实验,测试是使用原始的max-age还是新的,答案是新max-age
的,所以你应该能够实现你想做的事情。
重要的是要记住它max-age
是相对于Date
响应头的,而不是Last-Modified
,所以每当你的服务器设置一个max-age
24 小时的指令时,它就是说“从现在起 24 小时”。因此,假设这就是您想要的,您根本不必更改您max-age
的,只需始终返回 86400。
无论如何,这是我的实验的概述和转储。基本上,我点击了一个设置 ETag 并设置max-age
为 120 秒的测试 URL。因此,服务器返回了带有这些响应头的页面:
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 秒结束后,就在我下一次按 Enter 时,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 那样做。
(注意:为简洁起见,在这些示例转储中,我删除了不相关的标头,例如主机、连接/保持活动、内容编码/长度/类型、用户代理等)