因为最近面试经常会被问到304缓存的问题,因此在网上搜集了各种资料,小记一下
缓存有浏览器缓存,代理服务器缓存,服务端缓存等,这里着重记一下浏览器缓存
浏览器第一次像服务器发起请求时,如果有缓存,浏览器在返回信息里面会带上相应的缓存策略,下面介绍一下有哪些常用的缓存策略。
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 告知浏览器,我希望内容来自缓存,我并不关心被缓存响应,是否是新鲜的。
Last-modified
在浏览器第一次请求某一个资源时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间。
客户端请求验证缓存的有效性。
If-modified-since
客户端再次请求某个资源时请求头会带上这个属性。验证在上次修改的时间之后是否有再次修改。
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...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。