浏览器缓存
· 阅读需 7 分钟
浏览器的缓存类型比较多,例如:
- HTTP Cache: HTTP 缓存;
- Disk Cache: 将缓存写入到硬盘中;
- Memory Cache: 将缓存写入到内存中;
- Service Worker Cache;
强缓存
Disk Cache 和 Memory Cache 属于强缓存,是 HTTP 缓存的产物,强缓存的产生依赖于请求响应中的 cache-control 和 expires 的 headers 字段。这两个字段都用来设置缓存数据的有效时间。

当请求响应符合强缓存时,浏览器会根据 header 头中的字段类型进行缓存处理。通常情况下:
- Memory Cache: 会存放脚本、base64数据和字体等;
- Disk Cache: 会存放样式文件、图片或比较大的文件等;
此行为属于浏览器行为,服务器不可对其进行控制
内存缓存和硬盘缓存两者的区别:
| 内容缓存 | 强缓存 |
|---|---|
| Disk Cache | 长期存在,关闭浏览器后同样存在;存储文件空间很大 |
| Memory Cache | 短期存储,生命周期是会话级的,会话结束后将清除缓存;访问速度快、优先级高 |

协商缓存
当强缓存失效后,浏览器就会携带缓存标志向服务器发送请求。主要用到的 header:
- Etag / If-None-Match
- Last-Modified / If-Modified-Since
当收到请求的响应时,会携带:
Etag:服务器基于某种规则对资源生成的一个标志,类似于文件 hash。Last-Modified:服务器返回的文件最后修改的时间。
当发送请求的时候,浏览器会携带:
If-None-Match:对应的是Etag的值。If-Modified-Since:对应的是Last-Modified的值。
服务器根据这两个值进行匹配,如果相等,说明文件没有变化,返回 304,浏览器直接从缓存里面取;当不相等时,服务器发送最新的内容,状态码为 200。

301 和 304 状态码
- 301(Moved Permanently)当服务器返回301状态码时,表示被请求的资源已永久移动到了一个新的URL地址。客户端收到301响应后,会自动重定向到新的URL地址。搜索引擎会将原始URL的排名和索引等信息转移到新的URL上。因此,301重定向适用于资源永久性更改的情况。
- 304(Not Modified)当服务器返回304状态码时,表示客户端缓存的资源仍然有效,并且没有发生修改。这时,服务器不会返回实际的资源内容,而是告诉客户端可以直接使用本地缓存的版本。这样可以减少网络流量和服务器负载, 提高性能。
区别
- 301是永久重定向,要求客户端将请求的URL更新为新的URL,而304是缓存验证,告诉客户端可以使用本地缓存的版本。
- 301会导致客户端发起新的请求,而304不会发起新的请求,直接使用本地缓存。
- 301适用于资源永久移动的情况,而304适用于资源未被修改的情况。
- 301会改变搜索引擎对URL的索引,而304不会改变搜索引擎的索引。
应用场景
301:
- 网站重定向:当网站的URL结构发生变化或网站迁移时,可以使用301重定向将旧的URL重定向到新的URL,以保持搜索引擎的排名和用户的访问流量。
- 域名重定向:当网站更换域名时,可以使用301重定向将旧域名的请求重定向到新域名,以确保用户能够访问到正确的网站。
- 移动设备重定向:当网站有适用于移动设备的版本时,可以使用301重定向将桌面版本的URL重定向到移动版本的URL,以提供更好的移动用户体验。
304:
- 浏览器缓存验证:客户端在发送请求时会附带上资源的缓存标识(如
ETag或Last-Modified时间)。服务器可以使用304状态码来告诉客户端,资源未被修改,可以直接使用本地缓存,避免重新传输资源。 - 静态资源缓存:服务器可以使用304状态码配合缓存机制,使客户端在缓存有效期内直接使用本地缓存,减少网络流量和服务器负载。
- 加速CDN内容分发:当使用内容分发网络(CDN)时,CDN服务器可以使用304状态码来验证缓存的内容是否有效,避免不必要的数据传输。
Service Worker Cache
该缓存属于 PWA Cache Storage API,它有更精细的通过程序操作缓存的能力。缓存命中条件依赖于 fetch,是否从 ServiceWorker Cache 里面取缓存,完全依赖于 ServiceWorker 的脚本控制,这取决于用户的自定义设置。


浏览器刷新操作
在浏览器上进行不同的刷新操作,所发送的实际请求也是不同的。
| 操作 | 强缓存 | Service Worker Cache | 协商缓存 | 缓存 Headers 变动 |
|---|---|---|---|---|
| 刷新按钮或 Cmd+R | 有效 | 有效 |
