要回答您关于缓存为何起作用的问题,即使网络服务器不包含标头:
- 过期:
[a date]
- 缓存控制: max-age=
[seconds]
服务器恳请任何中间代理不要缓存内容(即,该项目应仅缓存在私有缓存中,即仅在您自己的本地计算机上):
但是服务器忘记包含任何类型的缓存提示:
- 他们忘记包含Expires(因此浏览器知道在该日期之前使用缓存的副本)
- 他们忘记包括Max-Age(所以浏览器知道缓存的项目可以使用多长时间)
- 他们忘记包含电子标签(所以浏览器可以做一个有条件的请求)
但他们确实在回复中包含了 Last-Modified日期:
Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT
因为浏览器知道文件被修改的日期,它可以执行一个条件请求。它将向服务器询问文件,但指示服务器仅在文件自 2012/10/16 3:13:38 以来已被修改时才发送文件:
GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
服务器收到请求,意识到客户端已经拥有最新版本。它不是发送 client 200 OK
,然后是页面内容,而是告诉您您的缓存版本是好的:
304 Not Modified
您的浏览器确实不得不遭受向服务器发送请求并等待响应的往返延迟,但它确实省去了重新下载静态内容的麻烦。
为什么选择最大年龄?为什么过期?
因为Last-Modified很烂。
并非服务器上的所有内容都有与之关联的日期。如果我正在即时构建页面,则没有与之关联的日期 -现在是. 但我完全愿意让用户将主页缓存 15 秒:
200 OK
Cache-Control: max-age=15
如果用户锤击F5,他们将继续获取缓存版本 15 秒。如果它是一个公司代理,那么在同一个 15 秒窗口中访问同一个页面的所有 67,198 个用户都将获得相同的内容 - 全部来自关闭缓存。为每个人赢得性能。
添加的优点Cache-Control: max-age
是浏览器甚至不必执行“条件”请求。
- 如果您仅指定
Last-Modified
,则浏览器必须执行If-Modified-Since
请求并观察304 Not Modified
响应
- 如果您指定
max-age
,浏览器甚至不必遭受网络往返;内容将直接从缓存中出来。
“Cache-Control: max-age”和“Expires”的区别
Expires
是现代Cache-Control: max-age
标头的旧版(c. 1998)等价物:
1998 年之后编写的任何网站都不应再使用Expires
,而应使用max-age
.
什么是ETag?
ETag类似于Last-Modified,不同之处在于它不必是日期 - 它只需是something
.
如果我从数据库中提取产品列表,服务器可以将最后一个rowversion
作为 ETag 而不是日期发送:
200 OK
ETag: "247986"
我的 ETag 可以是静态资源(例如图像、js、css、字体)或缓存渲染页面的 SHA1 散列(即,这是 Mozilla MDN wiki 所做的;它们散列最终标记):
200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
与基于Last-Modified的条件请求完全一样:
GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
304 Not Modified
我可以根据 ETag执行条件请求:
GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
304 Not Modified
AnETag
优于,Last-Modified
因为它适用于文件以外的事物,或者具有日期概念的事物。它只是