强缓存与协商缓存
浏览器缓存策略
请求资源时缓存的应用过程
- 浏览器在加载资源时根据
http header
判断是否命中强缓存,如果命中,则直接使用缓存里的资源,不会发送请求到服务器。 - 如果没有命中强缓存,浏览器会发送请求到服务器,服务器根据
http header
判断是否命中协商缓存,如果命中则浏览器会响应这个请求,但不会反悔资源,会告诉浏览器使用缓存里的资源。 - 如果协商缓存也没有命中,那么正常响应请求,返回资源。
强缓存和协商缓存的区别与联系
区别:命中强缓存不会发送请求到服务器,但是协商缓存需要向服务器发送请求(因为是否命中协商缓存由服务器判断)
共同点:都是从浏览器的缓存中获取资源
强缓存
开启强缓存需要 http
响应头中包含指定的字段: Expires
或 Cache-Control
。
Expires
Expires 的特点
Expires
是 http1.0
提出一个表示资源过期的 respone header
字段,他有以下特点:
- 返回的是绝对时间。
- GMT 格式的字符串表示,如:
Thu, 31 Dec 2037 23:55:55 GMT
Expires 的原理
Expires
字段的原理是:浏览器第一次请求资源的时候,服务器在 respone header
中添加 Expires
字段,浏览器将请求回来的资源以及 respone header
一并存到缓存中,当浏览器再次请求这个资源的时候,先从缓存中找到该资源,然后拿到上次缓存的 Expires
字段的值,与当前请求的时间作比较,如果发现当前请求的时间晚于上一次换粗的 Expires
字段的值,说明缓存失效了,重新请求资源,并更新 Expires
字段的值。
Expires 存在的问题
在介绍 Expires
的特点时我们知道, Expires
字段的值代表未来的一个绝对时间,比如 2018 年 1 月 1 日
,这会有什么问题呢?其实很明显,如果我本机时间与服务器时间相差较大的时候, Expires
过期很容易失效了。
Cache-Control
Cache-Control 的特点
正因为 Expires
的绝对时间存在上述的问题, http1.1
提出了一个新的 respone header
即: Cache-Control
,它具有以下特点:
- 返回的是相对时间
- 可以通过
Cache-Control
字段的属性值max-age
配置缓存的时间长度,单位是秒,如下:
Cache-Control:max-age=315360000
Cache-Control 的原理
Cache-Control
缓存的原理与 Expires
类似,区别在于过期判断:
Expires
是使用本机时间与服务器返回的一个绝对时间对比,这会出问题,上面也有讲过Cache-Control
则不同,它是使用上一次请求的时间加上设置的相对时间,计算出一个过期时间,与本次请求的时间作对比,使用的时间都是本机时间。
注意事项
Expires
与 Cache-Control
可以同时存在于 respone header
, Cache-Control
的优先级高于 Expires
。
协商缓存
浏览器自身就可以判断是否命中强缓存,但是协商缓存是由服务器来判断的,所以当强缓存没有命中后,浏览器会发送请求到服务器,服务器根据相应的 http header
判断是否命中协商缓存。如果命中协商缓存,则响应头的状态码为 304
即未改变(Not Modified),告诉浏览器使用缓存中的资源。
开启协商缓存有两种方案:
- 请求头:
If-Modified-Since
配合 响应头:Last-Modified
- 请求头:
If-None-Match
配合 响应头:ETag
Last-Modified / If-Modified-Since
原理
- 当浏览器第一次向服务器请求资源时,服务器在响应头中会添加
Last-Modified
字段,该字段的值代表资源的最后一次修改时间。 - 浏览器再向服务器发送请求时,会在请求头部添加字段:
If-Modified-Since
,该字段的值为之前缓存下来的Last-Modified
的值。 - 服务器拿到
If-Modified-Since
的值进行对比,如果一致则命中协商缓存,返回304
状态码,告诉浏览器从缓存中获取资源。 - 如果没有命中协商缓存,则正常返回资源,以及新的
Last-Modified
值,浏览器进行更新。
注意:在命中协商缓存的情况下,服务器不会在响应头中添加: Last-Modified
字段,因为没有必要。
缺点
有的时候会出现这种情况:资源实际已经被修改了,但是他的最后修改时间没有变,这就会导致新的资源无法得到更新
ETag / If-None-Match
正如 Last-Modified / If-Modified-Since
的缺点所描述的那样,为了避免这个问题,就有了 ETag / If-None-Match
。
原理
原理类似于 Last-Modified / If-Modified-Since
,不同的时候, ETag
不是资源的最后修改时间,而是服务器根据当前请求的资源生成的唯一标示,是一个字符串。
Last-Modified 与 ETag 的对比
字段值
Last-Modified
是资源的最后修改时间ETag
是当前请求的资源的唯一标示字符串
命中缓存后是否最为响应头返回
- 如果命中协商缓存,
Last-Modified
并不会最为响应头返回,因为没有必要 - 如果命中协商缓存,
ETag
仍然会作为响应头返回,因为不管资源有没有改变,资源的唯一标示又重新生成了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: git config 配置项
下一篇: WAF Bypass 介绍分析
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论