浏览器缓存类型
- 本地缓存,也叫强缓存。使用本地缓存时,浏览器可以直接从本地的内存或磁盘中获取内容,不需要与服务器产生实际的交互
- 协商缓存,也叫弱缓存。使用协商缓存时,浏览器需要先向服务器验证缓存内容的有效性,如缓存内容还是最新的,则浏览器可以使用该缓存
浏览器缓存控制
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