参考文献:https://www.cnblogs.com/chengxs/p/10396066.html
根据上图可知:
1.浏览器每次发起请求,都会在浏览器中查找该请求的结果和缓存标识
2.浏览器每次那会返回的请求结果都回把返回结果和缓存标识保存在浏览器中
以上两点是浏览器缓存机制的关键。
浏览器缓存分为两个部分:强缓存和协商缓存
强缓存
强缓存:向浏览器缓存查找请求结果,并根据结果和缓存规则决定是否使用缓存结果的过程。强缓存分为三种:
1.不存在该缓存结果和标识,强缓存失效,则直接向服务器发起请求(和第一次发起请求一致),如图:
2.存在缓存结果和缓存标识,但是结果失效,强制缓存失效,则使用协商缓存,如图:
3.存在该缓存结果和缓存标识,且结果还没有失效,强制缓存生效,直接返回该结果,如下
强缓存的缓存规则?
当浏览器向服务器发起请求的时候,服务器会将缓存规则放入HTTP的响应报文的HTTP头中和结果一起返回给浏览器,控制强缓存的字段是Cache-Control和Expires,Cache-Control优先级高于Expires
Expires
Expires是HTTP1.0控制网页缓存的字段,他是服务器返回结果缓存的到期时间,是一个绝对时间,固定时间。
Expires是HTTP1.0的字段,现在浏览器默认使用HTTP1.1,所以Expires已经被Cache-Control替代,原因因为是用服务端返回时间和客户端进行对比,由于时差,时区可能导致误差,所以使用Cache-Control。
Cache-Control
在HTTP1.1中,Cache-Control是重要规则,用于控制页面缓存,主要取值:
1.public:所有内容都被缓存(客户端和服务器都可缓存)
2.private:所有内容只有客户端可以缓存,Cache-Control的默认值
3.no-cache:客户端缓存内容,但是是否使用需要经过协商缓存来验证决定
4.no-store:所有内容都不会被缓存,不用强缓存,也不用协商缓存
5.max-age=xxx:缓存有效期,时间戳,相对时间(发起请求+时间戳和上次时间比较)
拓展:浏览器缓存放在那里,如何在浏览器中判断强缓存是否生效?
状态码是灰色的请求标识使用了强缓存,请求对应的size值则表示缓存的位置,分别是from memory cache(使用内存中的缓存,快速读取,进程关闭,内存清空)和form disk cache(使用硬盘中的缓存,会对磁盘进行I/O操作,读取慢),浏览器读取缓存的顺序为momery->disk
浏览器会把js和图片等解析执行后直接放入内存缓存中,所以刷新页面只需要从内存中读取缓存。css文件回放入硬盘文件,所以每次渲染从硬盘中读取。
协商缓存
协商缓存:强缓存失效后,浏览器携带缓存标识向服务器发起请求,服务器根据缓存标识决定是否使用缓存的过程,有两种情况:
1.协商缓存生效,返回304,如下:
2.协商缓存失效,返回200,如下:
同样,协商缓存的标识也在响应HTTP头中和请求结果一起返回给浏览器,控制协商缓存的字段有:Last-Modified/if-Modified-Since 和 Etag/if-None-Match(优先级高),
Last-Modified/if-Modified-Since(时间精确到秒)
1.Last-Modified是服务器响应头里,返回该资源在服务器最后被修改的时间,如下:
2.if-Modified-Since是客户端请求头里,请求头携带上次请求返回的Last-Modified值,通过这个下端告诉服务器上次请求资源最后被修改的时间。服务器收到请求,会根据请求头里面的if-Modified-Since的值,去和服务器中该资源的最后修改时间比较。如果腐恶去的最后修改时间大于if-Modified-Since的值,则返回最新资源,状态码是200;否则返回304,代表资源没更新,使用缓存。如图:
Etag/if-None-Match
1.Etag是服务器响应请求时,返回当前资源文件的唯一标识(服务器生成Hash值),如下:
2.if-None-Match是客户端再次发起请求,请求头里携带上次返回的Etag,通过这个字段告诉服务器该资源上次请求返回的唯一标识值。服务器收到请求,根据if-None-Match和该资源在服务器的Etag对比,一致就返回304使用缓存;不一致就返回最新资源,状态码200,如下:
总结
1.强缓存优先于协商缓存,如果强缓存生效,直接使用缓存,不生效在使用协商缓存。
2.协商缓存由服务器决定,会根据Last-Modified / If-Modified-Since和Etag / If-None-Match来判断,如果生效返回304状态码,使用缓存;失效就返回最新资源,状态码200;