HTTP 缓存 笔记

162 阅读3分钟

为什么需要缓存?

减少了数据的传输量,节约了网络带宽,减少了加载时间,提升了用户体验。

缓存类型

根据是否重新向服务器发起请求可以分为: 强制缓存和协商缓存

强缓存

以下为与强缓存相关的HTTP头部字段

字段实例优先级HTTP版本兼容性
ExpiresFri, 01 Jan 1990 00:00:00 GMT1.0
Cache-ControlCache-Control:max-age=60001.1相对低
PragmaPragma:no-cache若 Cache-Control 不存在 则地位与其一样1.0

Expires

包含资源的过期时间,它是一个绝对时间,如果系统涉及时区,则有可能会出问题。
若值为 0,则表示一个已经过去的时间,表示资源已经过期了。
因为是 1.0 版本的标准,兼容性好。

Cache-Control:

  1. max-age:用来设置资源可以被缓存多长时间,单位为秒;
  2. s-maxage:和 max-age 是一样的,不过它只针对代理服务器缓存;
  3. public:指示响应可被任何缓存区缓存;
  4. private:只能针对个人用户,而不能被代理服务器缓存;
  5. no-cache:不使用强缓存,需要与服务器验证,评估缓存响应的有效性;
  6. no-store:禁止一切缓存(这个才是不缓存的意思);
  7. must-revalidate:在缓存过期前可以使用,过期后必须向服务器验证;

Pragma

由于 Pragma 在 HTTP 响应中的行为没有确切规范,所以不能「可靠」替代 HTTP/1.1 中通用首部 Cache-Control,尽管在请求中,假如 Cache-Control 不存在的话,它的行为与 Cache-Control: no-cache 一致。建议只在需要兼容 HTTP/1.0 客户端的场合下应用 Pragma 首部。(from mdn)

协商缓存

当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了 If-Modified-Since 或者 If-None-Match 的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回 304 状态,加载浏览器缓存,并且响应头会设置 Last-Modified 或者 ETag 属性。

字段对应字段描述
Last-ModifiedIf-Modified-SinceGMT时间服务端资源的最后修改时间
If-Modified-SinceLast-ModifiedGMT时间
EtagIf-None-Match内容hash/文件信息服务器缓存资源的文件信息或文件内容生成的哈希值。1. Etag 的生成是一个消耗服务器资源的操作,所以才有强弱校验之分。(弱校验以 "W/" 开头)2. 有人不建议使用 etag 原因是在分布式服务器可能会出现文件没有修改,但是不同机器生成的etag不同导致没有效果。
If-None-MatchEtag内容hash/文件信息

到底谁优先级高呢?

www.ietf.org/rfc/rfc2616… 13.3.4 章节,当两个头都存在的时候,全部通过才会返回304.

参考链接

  1. 缓存 MDN developer.mozilla.org/zh-CN/docs/…

  2. www.ietf.org/rfc/rfc2616…