浏览器缓存类型
- 本地缓存,也叫强缓存。使用本地缓存时,浏览器可以直接从本地的内存或磁盘中获取内容,不需要与服务器产生实际的交互
- 协商缓存,也叫弱缓存。使用协商缓存时,浏览器需要先向服务器验证缓存内容的有效性,如缓存内容还是最新的,则浏览器可以使用该缓存
浏览器缓存控制
HTTP 1.1风格
服务器在返回资源到浏览器时,通过在HTTP响应头增加Cache-Control属性控制浏览器缓存

例子
Cache-Control: max-age=31536000 开启浏览器缓存,缓存有效时间max-age,单位为秒。在缓存有效期间,命中本地缓存,不需要发送网络请求到服务器获取资源,而是直接取浏览器本地资源。缓存过期后,命中协商缓存,要通过服务器认证,确认缓存还是最新版本,才允许浏览器使用。如缓存并不是最新版本,则服务器返回完整资源。
Cache-Control: no-store 不开启任何浏览器缓存
Cache-Control: no-cache 不开启浏览器本地缓存,开启浏览器协商缓存,每次都要先通过服务器认证,确认缓存还是最新版本,才允许浏览器使用。如缓存并不是最新版本,则服务器返回完整资源
Cache-Control: public 资源可以被任何对象缓存,包括代理服务器等
Cache-Control: private 资源只可以被单个用户缓存,一般是指本地浏览器缓存
Cache-Control: must-revalidate 当资源需要服务器认证是否为最新版本时,假如连接不上服务器,则不能使用过期缓存。 反过来,不开启must-revalidate 则会使用过期缓存
HTTP 1.0风格
服务器在返回资源到浏览器时,通过在HTTP响应头增加Expires属性开启浏览器本地缓存。相当于HTTP 1.1风格的max-age
如果在Cache-Control响应头设置了 max-age 或者 s-max-age 指令,那么 Expires 头会被忽略
例子
Expires: Wed, 21 Oct 2015 07:28:00 GMT
隐式开启
也叫启发式缓存。服务器在返回资源到浏览器时,通过在HTTP响应头增加Last-Modified属性开启浏览器协商缓存,同时隐式开启本地缓存。根据HTTP规范算法,本地缓存时间为Date响应头的时间减去Last-Modified的时间,得出的时长再除以10
假如已通过前两种方式开启浏览器缓存,即使用了Cache-Control或Expires,隐式开启将被忽略
服务器认证缓存是否为最新版本
在浏览器本地缓存过期,或开启了no-cache的情况下,浏览器不会直接使用本地缓存,而是使用协商缓存,先向服务器发送请求,以确认缓存是否为最新版本。在这次请求中,服务器将会带上If-None-Match或If-Modified-Since,属性的值分别对应获取当前浏览器缓存内容的那次响应的ETag值和Last-Modified值。同时存在的情况下,If-None-Match的优先级高于If-Modified-Since。
ETag
服务器端开启ETag后,第一次请求资源,会通过某种算法计算ETag,然后将ETag放到响应头里面。浏览器将会缓存此ETag,如果浏览器再次请求同一资源,会把ETag的值放到请求头的If-None-Match属性里面。服务器接收第二次请求后,把将要返回的内容再次计算ETag,然后与请求头的If-None-Match的值比对。如果前后两次请求需要返回的内容有变化,则ETag的值也不同,服务器会返回完整的响应,响应状态码为200。否则,服务器返回不完整的响应,响应状态码为304
Last-Modified
与ETag类似,只是不需要计算一个ETag,而直接取用资源的修改时间来代替。Last-Modified的优点是免去了计算ETag的消耗,缺点是修改时间一般只能精确到秒,还有Last-Modified值不同有可能资源内容却相同
通过Chrome的Network查看是否使用缓存
| Status | Size | |
|---|---|---|
| 200 | (from memory cache) | 使用浏览器本地缓存,且缓存在内存中 |
| 200 | (from disk cache) | 使用浏览器本地缓存,且缓存在磁盘中 |
| 304 | 报文大小 | 使用浏览器协商缓存,且通过服务器验证,缓存为最新版本后,浏览器使用缓存 |
| 200 | 报文大小 | 没有使用浏览器缓存,或协商缓存不是最新版本,从服务器获取最新资源 |
使用浏览器查看缓存状态时,不要在开发者工具中勾选Disable cache
默认情况
在没有定义Cache-Control和Last-Modified的情况下,需要重新验证缓存有效性,相当于
Cache-Control: no-cache
# 或
Cache-Control: max-age=0, must-revalidate