是的,304响应可以包含新的max-age
(或ETag,或其他响应头)。
我使用Firefox 4进行了一个实验,以测试原始的max-age是否被遵循,答案是新的max-age
被遵循,所以你应该能够实现你想要做的事情。
重要的是要记住,max-age
是相对于响应头中的Date
而不是Last-Modified
的时间,因此每当服务器设置24小时的max-age
指令时,它表示“从当前时间开始的24小时”。因此,假设这就是你想要的,你不需要改变你的max-age
,只需始终返回86400即可。
无论如何,这里是我的实验概述和转储。基本上,我访问了一个测试URL,设置了一个ETag并将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
然后我重复在地址栏中按“Enter”加载页面(但不强制执行硬刷新)。由于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一样做。
(注意:为了简洁起见,在这些示例中删除了不相关的头信息,例如主机、连接/保持活动状态、内容编码/长度/类型、用户代理等。)