由于最近面试常常会被问到304缓存的问题,所以在网上搜集了各类资料,小记一下面试
缓存有浏览器缓存,代理服务器缓存,服务端缓存等,这里着重记一下浏览器缓存segmentfault
浏览器第一次像服务器发起请求时,若是有缓存,浏览器在返回信息里面会带上相应的缓存策略,下面介绍一下有哪些经常使用的缓存策略。浏览器
Expires 过时时间,这是HTTP1.0就有的。客户端在首次请求服务器资源的时候服务器设置一个资源的过时时间,这个时间是绝对的,若是设置的缓存策略是这个,那么浏览器再次请求的时候会跟所请求资源的过时时间比对一下,若是在过时时间以内,那么从本地读取,不然会看看是否设置了其余缓存策略,按照其余策略来,没有的话就向服务器发起请求了。咱们能够看出,这个是否发起请求跟客户端本地时间有很大关系,若是时间设置的不对,那么缓存策略就有可能失效。缓存
Cache-control 这一项的可选值有 max-age/no-cache/no-store/public/private/must-revalidate/s-maxage
这里面最经常使用到的有max-age/no-cache/no-store, max-age服务器
max-age 会设置一个相对的过时秒数,即从首次请求算起,在这一段时间内都不会过时。
no-cache 响应是能够被缓存的,只不过再跟服务器进行新鲜度匹配以前都不会提供给客户端使用。因此应该叫do-not-serve-from-cache-without-revalidation更好一点。
no-store 绝对禁止缓存,客户端缓存不能复制响应,以后的每次请求都从服务器获取资源。
must-revalidate 在跟服务器进行新鲜度验证以前,缓存不能够把缓存的响应给浏览器。若是原始服务器不可用,会返回504 Gateway Timeout的错误。
only-if-cached 告知浏览器,我但愿内容来自缓存,我并不关心被缓存响应,是不是新鲜的。spa
Last-modified
在浏览器第一次请求某一个资源时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间。.net
客户端请求验证缓存的有效性。代理
If-modified-sinceblog
客户端再次请求某个资源时请求头会带上这个属性。验证在上次修改的时间以后是否有再次修改。资源
If-none-match
客户端再次请求某个资源时请求头会带上这个属性。属性值是第一次请求该资源时返回的etag值
验证在上次修改以后是否有新的版本。
缓存命中速度
缓存命中 > 缓存再验证成功 > 缓存未命中 = 缓存再验证失败;
缓存命中优先级
Cache-Control http1.1 > Expires > Pragma http1.0来决定是否 (200 from cache)
根据Last-Modified http1.0 和 ETag http1.1 来验证是否返回 (304 Not Modified) 二者都有,就必须同时验证,而且二者都知足才会返回304;
盗图一张,整个的浏览器请求的时候缓存验证过程以下图
首先看有没有缓存,没有的话直接请求服务器,这时候没出意外的话,正常地返回应该是200
有缓存而后看是否过时,没过时的话就用缓存的资源了这时候不会发器请求
若是过时了再向服务器发起请求看资源是否有修改,若是没修改则返回304,若是修改了则返回200连同最新的资源一块儿返回,更新浏览器缓存副本。
参考文章
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
https://my.oschina.net/leejun...
http://blog.csdn.net/pojianbi...
https://segmentfault.com/a/11...