设计一个完美的HTTP缓存策略

作为一个前端,了解http缓存是非常必要,它不仅是面试的必要环节,也更是实战开发中必不可少需要了解的知识点,本文作者将从缓存的概念讲到如何在业务中设计一个合理的缓存架构,带你一步一步解开http缓存的神秘面纱。

2、http缓存定义

当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。http缓存一般针对GET请求,POST请求一般不会缓存,因为POST请求执行的任务都是对服务器产生副作用或者非幂等性的任务,既然要改变服务器资源,自然请求是要进入服务器进行处理的。缓存带来的好处是巨大的,减少了http请求,自然也就减少的服务端压力,并且增加了资源的访问速度,但是胡乱使用缓存,将会带来资源的不及时更新,甚至资源更新错位,灾难也是巨大的。
http缓存分为强缓存和协商缓存,下面带大家一一了解两种缓存机制。

3、强缓存 3.1、强缓存定义

如果命中缓存,直接从缓存中拿数据,请求不会经过服务器,返回的http状态码为200(from disk cache)

设计一个完美的HTTP缓存策略

下面给一张流程图来说明强缓存的请求过程,为了方便假设浏览器存在一个缓存数据库(其实就是disk磁盘,缓存数据存放的地方)。

设计一个完美的HTTP缓存策略

设计一个完美的HTTP缓存策略

仔细看上面的流程图,强缓存的最大特点就是在命中缓存的情况下不会经过服务器,而是直接返回。

3.2、Http头Expires/Cache-Control设置强缓存

Cache-Control里面存在多个属性来控制缓存,设置强缓存即设置资源的有效期,属性为max-age.
下面使用Express给大家演示一下

app.get('/script1.js', function (req, res, next) { // res.header('Cache-Control', 'must-revalidate, max-age=600') // res.header('Content-Type', 'text/html') res.header('Cache-Control', 'max-age=20') res.sendFile(__dirname + '/script.js') })

设计一个完美的HTTP缓存策略

Expires和max-age都是用于控制缓存的生命周期。不同的是Expires指定的是过期的具体时间,例如Sun, 21 Mar 2027 08:52:14 GMT,而max-age指定的是生命时长秒数315360000。
区别在于Expires是 HTTP/1.0 的中的标准,而max-age是属于Cache-Control的内容,是 HTTP/1.1 中的定义的。但为了想向前兼容,这两个属性仍然要同时存在。max-age是要优先于Expires的。

4、协商/对比缓存 4.1、定义

协商缓存与强制缓存的不同之处在于,协商缓存每次读取数据时都需要跟服务器通信,并且会增加缓存标识。在第一次请求服务器时,服务器会返回资源,并且返回一个资源的缓存标识,一起存到浏览器的缓存数据库。当第二次请求资源时,浏览器会首先将缓存标识发送给服务器,服务器拿到标识后判断标识是否匹配,如果不匹配,表示资源有更新,服务器会将新数据和新的缓存标识一起返回到浏览器;如果缓存标识匹配,表示资源没有更新,并且返回 304 状态码,浏览器就读取本地缓存服务器中的数据。
协商缓存的最大特点是要经过服务器验证的,下面我们来讲解协商缓存的验证流程。
第一次访问:

设计一个完美的HTTP缓存策略

再次访问:

设计一个完美的HTTP缓存策略

还是给一张流程图来说明。(图是盗的,协商缓存也可以成为对比缓存,图中的对比缓存就是协商缓存)

设计一个完美的HTTP缓存策略

4.2、协商缓存如何验证

第一次请求将response header的Last-Modified和Etag存起来,在第二次请求通过request header的If-Modified-Since和If-None-Match传到服务端进行验证,如果命中缓存,返回304,不带返回的数据,浏览器自动从缓存中获取数据资源,若未命中缓存返回200,带上数据资源。

** Last-Modified:**
服务器在响应请求时,告诉浏览器资源的最后修改时间。

设计一个完美的HTTP缓存策略

** If-Modified-Since:**
再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;
若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

设计一个完美的HTTP缓存策略

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/802113600b04f8976b457661f1c02369.html