回答您关于缓存为何有效的问题,即使网络服务器不包含标头:
-
过期:
[a date]
-
缓存控制: max-age=
[seconds]
服务器恳请任何中间代理不要缓存内容(即该项目应仅缓存在私有缓存中,即仅在您自己的本地计算机上):
但是服务器忘记包含任何类型的缓存提示:
- 他们忘记包含 Expires(因此浏览器知道在该日期之前使用缓存的副本)
- 他们忘记包含 Max-Age(这样浏览器就知道缓存的项目可以使用多长时间)
- 他们忘记包含 电子标签(因此浏览器可以执行有条件的请求)
但他们确实在回复中包含了Last-Modified日期:
Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT
因为浏览器知道文件被修改的日期,它可以执行conditional request。它将向服务器询问文件,但指示服务器仅在文件自 2012/10/16 3:13:38 以来被修改时才发送文件:
GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
服务器收到请求,意识到客户端已经拥有最新版本。而不是发送客户端200 OK,然后是页面内容,而是告诉您您的缓存版本是好的:
304 Not Modified
您的浏览器确实不得不遭受向服务器发送请求并等待响应的往返延迟,但它确实省去了重新下载静态内容的麻烦。 p>
为什么要最大年龄?为什么过期?
因为 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 标头的旧版(约 1998 年)等价物:
1998 年以后编写的任何网站都不应再使用Expires,而应使用max-age。
什么是 ETag?
ETag 类似于 Last-Modified,不同之处在于它不必是日期 - 它只需是 @ 987654343@.
如果我从数据库中提取产品列表,服务器可以将最后一个 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
ETag 优于 Last-Modified,因为它适用于 文件 之外的东西,或者具有 日期 概念的东西。它只是是