浅谈强缓存和协商缓存

浅谈强缓存与协商缓存

最近面试被问到很多次关于http缓存的问题,在此做下笔记以此记录。话不多说,先来看张图来直观感受下http缓存的整体流程。

浅谈强缓存和协商缓存

强缓存

当浏览器向服务器请求资源时,首先检查有无缓存。这个阶段不需要发送http请求。

无缓存的话,直接向服务器发送请求,服务器正常响应,返回响应结果,缓存标识存入缓存中。

有缓存的话检查缓存是否过期。判断缓存是否过期的字段是响应头中的(ExipresCache-Control).其中:

Exipres是在http/1.0时期使用的字段,值是具体的时间点。例如:

Expires:Wed,22 Nov 2019 08:41:00 GMT

表示资源在2019年11月22号8点41分过期,过期了就要向服务端发送请求了。

Cache-Control是在http/1.0时期使用的字段。它的值可以结合多个属性来使用,例如:

public:客户端和代理服务器都能进行缓存。因为一个请求有时候不仅需要浏览器和服务器参与,还要经过一个或多个代理服务器参与。

private:只有客户端才能进行缓存。

no-cache:跳过强缓存阶段,进入协商缓存,即直接发送http请求。

no-store:不进行任何缓存。数据由服务端响应返回。

max-age:值为时间段,单位为ms,例如:

Cache-Control:max-age=3600

表示缓存数据一小时后过期。一小时后就要向服务端发送请求了,即进入协商缓存阶段。

当强缓存失效后,进入协商缓存阶段,这个时候就需要发送http请求了。

协商缓存:

当浏览器第一次向服务器请求时,服务器会在响应头中返回缓存tag字段。tag字段主要分为两种:Last-ModifiedEtag字段。当强缓存失效时,浏览器在请求头中携带相应的缓存tag(If-Modified-SinceIf-None-Match)向服务端发起请求,服务端根据缓存tag值来判断要不要使用缓存。这就是协商缓存阶段。

Last-Modified:当浏览器第一次请求服务器时,服务器会在响应头中返回Last-Modified字段,字段值为服务器资源最近一次被修改的时间time1。

浏览器在接收到Last-Modified响应头后,如果下次再发送同样的请求,就会在请求头中携带If-Modified-Since字段,值为上次服务器响应头返回的时间time1,

服务器在接收到本次请求后,将time1和服务端资源最近一次被修改的时间time2进行比较,

如果time1<time2,说明资源更新了,服务端开始响应浏览器请求,返回响应结果,缓存标识。

如果time1=time2,说明服务端资源未更新,浏览器直接取缓存结果,服务端不进行响应,返回code304。

Etag:Etag是服务器根据当前文件内容,给文件生成的唯一标识。只要里面的内容有变动,这个值就会改变。服务器通过Etag字段将这个值value1传给浏览器。当浏览器再次请求时,通过请求头的If-None-Match字段,值为value1,发送给服务器。

服务器在接受到If-None-Match字段后,会将value1的值和自身Etag的值value2进行对比:

如果value1==value2,说明资源未更新,浏览器取缓存数据,返回304。

如果value1!=value2,说明资源更新了,服务端进行响应,返回新的资源和缓存Tag。

Last-Modified和Etag对比:

精确度:在精确度上Etag要高于Last-Modified,

性能:在性能上Last-Modified高于Etag。

 

参考文章:

https://www.cnblogs.com/jin-zhe/p/11586327.html

https://mp.weixin.qq.com/s/mqX-eCfGEY9DveG9-3BPiQ