一、缓存过程分析:
浏览器和服务器的通信模式为应答模式,即:浏览器发送http请求 ->服务器响应该请求。那么浏览器第一次拿到服务器返回的结果,根据HTTP头的缓存标识,决定是否缓存返回的结果。
过程图如下
由上图可知:
① 浏览器每次http请求都会在缓存中寻找该请求结果和缓存标识
② 浏览器每次请求都会把服务器的返回结果和缓存标识缓存在浏览器中
二、浏览器(http)缓存的两个基本类型
1、强制缓存:
1.1 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致),如下图:
1.2 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果,如下图
1.3 存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存(暂不分析),如下图
2、强制缓存:
当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,
控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。
2.1 Cache-Control 和 expires
在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:
- public:所有内容都将被缓存(客户端和代理服务器都可缓存)
- private:所有内容只有客户端可以缓存,Cache-Control的默认取值
- no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
- no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
- max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
由上面的例子我们可以知道:
- HTTP响应报文中expires的时间值,是一个绝对值
- HTTP响应报文中Cache-Control为max-age=600,是相对值
由于Cache-Control的优先级比expires,那么直接根据Cache-Control的值进行缓存,意思就是说在600秒内再次发起该请求,则会直接使用缓存结果,强制缓存生效。
注:在无法确定客户端的时间是否与服务端的时间同步的情况下,Cache-Control相比于expires是更好的选择,所以同时存在时,只有Cache-Control生效。
3、协商缓存:
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
控制协商缓存的字段主要是 :Last-Modified / If-Modified-Since 、 Etag / If-None-Match
其中 Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since
主要有以下两种情况:
3.1 协商缓存生效,返回304,如下:
3.2 协商缓存失效,返回200和请求结果结果.
如下
协商缓存控制字段:
① Last-Modified / If-Modified-Since
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。
If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。
服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,
则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件
② Etag / If-None-Match
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。
If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。
服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;
不一致则重新返回资源文件,状态码为200
总结:
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,禁止强缓存(cache-control:no-chache),若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存