为什么需要缓存?
减少了数据的传输量,节约了网络带宽,减少了加载时间,提升了用户体验。
缓存类型
根据是否重新向服务器发起请求可以分为: 强制缓存和协商缓存
强缓存
以下为与强缓存相关的HTTP头部字段
| 字段 | 实例 | 优先级 | HTTP版本 | 兼容性 |
| Expires | Fri, 01 Jan 1990 00:00:00 GMT | 低 | 1.0 | 高 |
| Cache-Control | Cache-Control:max-age=6000 | 高 | 1.1 | 相对低 |
| Pragma | Pragma:no-cache | 若 Cache-Control 不存在 则地位与其一样 | 1.0 | 高 |
Expires
包含资源的过期时间,它是一个绝对时间,如果系统涉及时区,则有可能会出问题。
若值为 0,则表示一个已经过去的时间,表示资源已经过期了。
因为是 1.0 版本的标准,兼容性好。
Cache-Control:
- max-age:用来设置资源可以被缓存多长时间,单位为秒;
- s-maxage:和 max-age 是一样的,不过它只针对代理服务器缓存;
- public:指示响应可被任何缓存区缓存;
- private:只能针对个人用户,而不能被代理服务器缓存;
- no-cache:不使用强缓存,需要与服务器验证,评估缓存响应的有效性;
- no-store:禁止一切缓存(这个才是不缓存的意思);
- 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-Modified | If-Modified-Since | GMT时间 | 服务端资源的最后修改时间 |
| If-Modified-Since | Last-Modified | GMT时间 | |
| Etag | If-None-Match | 内容hash/文件信息 | 服务器缓存资源的文件信息或文件内容生成的哈希值。1. Etag 的生成是一个消耗服务器资源的操作,所以才有强弱校验之分。(弱校验以 "W/" 开头)2. 有人不建议使用 etag 原因是在分布式服务器可能会出现文件没有修改,但是不同机器生成的etag不同导致没有效果。 |
| If-None-Match | Etag | 内容hash/文件信息 |
到底谁优先级高呢?
www.ietf.org/rfc/rfc2616… 13.3.4 章节,当两个头都存在的时候,全部通过才会返回304.
参考链接