何为缓存?
再次获取的资源不需要从服务器中获取,直接在本地内存空间中取出的操作。一般需要缓存的是更新频率不高的静态资源,比如图片等。
1. MDN定义缓存的分类
-
私有缓存
“私有缓存”,通常指浏览器缓存。可以通过设置Cache—Control:private来达到缓存私有的目的。一般来说,个性化内容通常是存储在私有缓存 中,以防用户私密信息的泄露。一定程度上来说,本文章重点介绍的强缓存和协商缓存这两种浏览器缓存,可以归类为私有缓存。
-
共享缓存
“共享缓存”,可细分为“代理缓存”和“托管缓存”。其中“托管缓存”有反向代理、CDN(内容分发网络)以及service worker和缓存API的组合。
2.强缓存——基于age的缓存策略
基于age的缓存策略
通过age与max-age / Expires对比来判断缓存的状态。当age没有超过设置的有效时间时,缓存的状态是“fresh”——有效;相反地,如果已经超过了设置的有效时间,缓存的状态即为“stale”——过期。
- 命中强缓存的状态码:200 ok
- max-age:
定义强缓存的有效时间段,其值是一个以秒 为单位的时间段;也就是一个相对时间,不受系统时间设置的影响。若请求中同时出现max-age和Expires,则以max-age为主导。
这是HTTP1.1提出的一个解决方案。因为利用Expires来设置强缓存的有效时间,一方面其时间格式很难被解析;另一方面,用户可以通过人为设置系统时间来使原本已失效的强缓存“复活”,这会带来安全威胁。
Cache-Control:max-age=604800
- Expires:
定义强缓存的最晚失效时间点,其值是一个具体的时间点;也就是一个绝对时间。
这是HTTP1.0提出的一个方案。实际上,自从max-age被广泛应用后,Expires已经不用刻意设置了。
3.协商缓存(响应验证)
-
命中协商缓存的状态码:304 Not Modified
-
请求头If-None-Match— 响应头ETag
在发送HTTP请求时, 如果带上If-None-Match:etag1(etag1是上一次请求服务器响应的ETag值),etag1会与此次服务器返回的响应中的ETag比对,若两个值一致,则说明资源未被更改,协商缓存有效,返回不带任何内容的304状态码;否则协商缓存失效。 -
请求头If-Modified-Since — 响应头Last-Modified
If-Modified-Since+Last-Modified的原理和上述If-None-Match+ETag基本一致。区别在于,如果这两个属性同时出现,If-None-Match+ETag的优先级比If-Modified-Since+Last-Modified高。此外,虽然在缓存方面,Last-Modified看起来好像没有什么意义;然而,Last-Modified作用不止如此,它是一个标准的HTTP请求头,比如内容管理系统也是使用它来显示上一次修改的时间。所以,出于更加周全的考虑,在浏览器缓存设置时,最好同时提供这两对“CP”。
总结:返回304状态码的过程
4.细说Cache-Control
Cache-Control: max-age / private / public / no-cache / no-store
max-age: 设置强缓存的有效时间段。no-cache:也称为“强制重新验证”。它不会阻止响应的缓存,而是阻止在没有重新验证的情况下重用响应,也就是每次都进行协商缓存的判断,以达到总是从服务器获取最新资源的目的。在响应中添加 Cache-Control: no-cache 以及 ETag 和 Last-Modified。 此时若资源已更新,则客户端将收到 200 ok的响应。 若资源未更新,则收到304 Not Modified响应no-store:阻止存储响应——不使用缓存,每次都从服务器获取资源,但是不会删除相同的URL中在此之前的缓存;另外,会使浏览器的前进后退功能失效。private:设置私有缓存。publice:设置共享缓存。
5.常见操作对浏览器缓存的影响
| 操作类型 | 强缓存 | 协商缓存 |
|---|---|---|
| 手动刷新/f5 | 有效 | 失效 |
| 强制刷新ctrl+f5 | 失效 | 失效 |
| 一般操作 | 有效 | 有效 |
一般操作:URL输入回车、链接跳转、新建标签页、前进后退