一、强缓存
1、http1.0时期有两个字段 Pragma 和 Expires
Pragma
Pragma:no-cache: 每次从缓存服务器取缓存数据都要先发起请求到源头服务器进行验证。
Expires
Expires:GMT格式时间:设置缓存过期时间(例如Expires:Wed, 21 Oct 2015 07:28:00 GMT)。当系统时间早于该时间时,每次请求直接从缓存服务器取数据。
如果想不缓存数据,应设置 Pragma:no-cache且Expires:0
2、http1.1时期加入字段 Cache-control
Cache-control
Cache-control:public:客户端和代理服务器都可以缓存
Cache-control:private:只能客户端缓存
Cache-control:max-age=n:缓存数据n秒后失效
Cache-control:no-store:数据不被缓存
Cache-control:no-cache:每次从缓存服务器取缓存数据都要先发起请求到源头服务器进行验证。
请求头和响应头都可以设置Cache-control,区别在于
客户端的请求头中只有设置了Cache-control为:'no-store' | 'no-cache' | 'max-age=0'才会生效(也就是客户端不想走强缓存的时候生效),除非后端对这个字段做特殊处理
在谷歌浏览器中,命中强缓存后会有两种情况
第一种:from memory cache(内存缓存),缓存数据会随着浏览器关闭而失效
第二种:from disk cache(硬盘缓存),缓存数据不会随着浏览器关闭而失效
优先级 Pragma > Cache-control > Expires (Pragma和Expires是旧产物,但可以向下兼容)
二、协商缓存
1、什么时候进行协商缓存
· 响应头中没有Cache-Control和Expires
· Cache-Control和Expires过期
· Cache-Control:no-cache时
2、协商缓存字段
Last-Modified(根据文件的修改时间决定是否读取缓存)
Last-Modified:GMT格式时间:设置在响应头,代表文件在服务器最后一次修改时间
if-Modified-Since:GMT格式时间:设置在请求头,值为该文件上次响应头的Last-Modified,服务器可以根据该时间与服务器中该资源的最后修改时间进行对比,若不同则返回状态码为200的新响应数据,若相同则返回304的空报文。
Etag(根据文件的唯一标识决定是否读取缓存)
Etag:唯一标识:设置在响应头,代表文件在服务器的唯一标识
If-None-Match:唯一标识:设置在请求头,值为该文件上次响应头的Etag,服务器可以根据该标识与服务器中该资源的唯一标识进行对比,若不同则返回状态码为200的新响应数据,若相同则返回304的空报文。
优先级 Etag > Last-Modified
三、浏览器自带启发式算法进行强缓存
如果响应头没设置Cache-Control和Expires,但设置了Last-Modified,部分浏览器会自带缓存:
缓存时间 = (Date - Last-Modified)/ 10%
ps:开发时,有时候修改了页面上的某个样式,在页面上刷新了但没有生效,因为是命中了强缓存,获取了本地资源。所以需要Ctrl+F5(强制刷新)一下(F5会触发协商缓存更新,Ctrl+F5会触发协商缓存和强缓存更新)
crtl+F5会给请求头添加Pragma: no-cache 或 Cache-Control: no-cache F5只会给请求头添加If-Modified-Since 或 If-None-Match