# http 缓存
# 强缓存和协商缓存
- 强缓存时利用 Expires(/ɪk'spaɪəz/ )或者 Cache-Control 这两个 http header 实现的,都用来表示资源在客户端缓存的有效期。在 chrome 控制台的 Network 选项中可以看到该请求返回 200 的状态码,并且 Size 显示 from disk cache 或 from memory cache。
- 协商缓存利用的是【Last-Modified、If-Modified-Since】、【ETag、If-None-Match】这两对 header 来管理的。 协商缓存生效,返回 304 和 Not Modified 协商缓存失效,返回 200 和请求结果协商缓存可以通过设置两种 HTTP Header 实现:Last-Modified 和 ETag
- 两者联系:强缓存就是给资源设置个过期时间,客户端每次请求资源时都会看是否过期;只有在过期才会去询问服务器。所以,强缓存就是为了给客户端自给自足用的(浏览器会从本地磁盘或内存中读取缓存并返回 200 状态)。而当某天,客户端请求该资源时发现其过期了,这是就会去请求服务器了,而这时候去请求服务器的这过程就可以设置协商缓存。这时候,协商缓存就是需要客户端和服务器两端进行交互的。
# 浏览器缓存刷新
- 在地址栏中输入网址后按回车或者点击转到按钮
浏览器以最少的请求来获取网页的数据,浏览器会对所有没有过期的内容直接使用本地缓存即使用强缓存,从而减少了对服务器的请求,Expires、max-age 标志只对这种方式有效。
- 按 F5 或浏览器刷新按钮
浏览器会在请求中附加必要的缓存协商,但不允许浏览器直接使用本地缓存即跳过强缓存的判断,直接进行协商缓存的判断,Last-Modified、ETag 在这种方式发挥作用。
- 按 Ctrl+F5 或按 Ctrl 并点击刷新按钮
强制刷新,完全不使用缓存
# Cache 缓存策略

# 返回 304 状态码的情况
// response header
ETag: '5c20abbd-e2e8'
Last-Modified: Mon, 24 Dec 2019 09:49:49 GMT
// request header 变为
If-None-Match: '5c20abbd-e2e8'
If-Modified-Since: Mon, 24 Dec 2019 09:49:49 GMT
# 场景一
● Request Headers 的 Cache 头域
If-Modified-Since:即本地文件的修改时间。
● Response Headers 的 Entity
Last-Modified:即服务器上文件的修改时间。
详解: 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果在 If-Modified-Since 字段指定的日期时间后,资源发生了更新,服务器会接受请求,就会返回 200 和新的文件内容。如果没有更新,那么返回 304,客户端就直接使用本地缓存文件。
# 场景二
● Request Headers 的 Cache 头域
If-None-Match
● Response Headers 的 Entity
ETag
详解:在 HTTP Response 中添加 ETag 信息。 当用户再次请求该资源时,将在 HTTP Request 中加入 If-None-Match 信息(ETag 的值)。如果服务器验证资源的 ETag 没有改变(该资源没有更新),将返回一个 304 状态告诉客户端使用本地缓存文件。否则将返回 200 状态和新的资源和 Etag。使用这样的机制将提高网站的性能。 ETag 是 HTTP1.1 产物,服务器通过某种算法,给资源计算出一个唯一的标志符,可能是一个资源的 MD5 值。

# Cache-Control
首部字段 Cache-Control 能够控制缓存
- 缓存请求指令

- 缓存响应指令

- 指令作用
1)Cache-Control: public
表明其他用户也可以利用缓存
2)Cache-Control: private
缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存
3)Cache-Control: no-cache
防止从缓存中返回过期的资源。如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。
4)Cache-Control: no-store
不进行缓存
no-cache 和 no-store 的区别: no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源。no-store 才是真正地不进行缓存。
5)Cache-Control: max-age=604800(单位:秒)
客户端:发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。
服务端:服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再作确认,而 max-age 数值代表资源保存为缓存的最长时间。
6)Cache-Control: min-fresh=60(单位:秒)
要求缓存服务器返回至少还未过指定时间的缓存资源。
7)Cache-Control: max-stale=3600(单位:秒)
指示缓存资源,即使过期也照常接收。
8)Cache-Control: only-if-cached
表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码 504 Gateway Timeout。
9)Cache-Control: must-revalidate
代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
10)Cache-Control: proxy-revalidate
要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
11)Cache-Control: no-transform
无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。
# Cache-Control 和 ETag 的区别
- Cache-Control 的首部字段较多
- 倘若 Cache-Control 设置的缓存没过期,那直接从本地读取缓存即可,返回 200(from cache),不需要向服务端发起请求。
- 使用 ETag 会向服务端发起请求,校验后服务端再决定是否返回资源。
# 强缓存与弱缓存的区别
- 获取资源形式: 都是从缓存中获取资源的。
- 状态码:强缓存返回 200(from cache),弱缓存返回 304 状态码
- 请求(最大区别):强缓存不发送请求,直接从缓存中取。弱缓存需要发送一个请求,验证这个文件是否可以使用(有没有被改动过)。
- 缓存位置
- memory cache:将资源缓存到内存里面。刷新页面就会情况
- disk cache:将资源缓存到磁盘中。刷新页面不会清空