这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
一、前言
大家好,我是inline,一个专注前端领域的同学。今天犹豫了很久要不要写http的强缓存和协商缓存,写的话 掘金很多大佬的文章都已经说的很详细很易懂了,有耍大刀和水文章的嫌疑。但是不写又想自己做个总结,写出来加深一下印象。犹犹豫豫的还是决定写一篇,如果有哪里说的有误不详细还望各位看官多多包容体谅。
二、强缓存
强缓存就是本地缓存
浏览器首次请求资源后,需要再次请求时,浏览器会首先获取该资源缓存的header
信息,然后根据Cache-Control
和expires
来判断该资源在本地缓存否过期。若没过期则直接从本地缓存中获取资源信息,浏览器就不再向服务器重新请求资源,如过期则需重新发送请求,重新缓存资源,更新缓存时间。
强缓存是利用http请求头中的Expires
和Cache-Control
两个字段来进行控制,用来表示资源的缓存时间。
Expires
Expires是http1.0的规范,它的值是一个GMT格式的绝对时间字符串。
expires: Thu, 17 Nov 2022 10:06:35 GMT
复制代码
Cache-Control
Cache-Control是http1.1中出现的,它的值是一个相对时间。
cache-control:max-age=31536000
复制代码
Expires和Cache-Control的区别
这两个值都是用来控制缓存时间的,那它们两个有什么区别吗?
首先一个是绝对时间一个是相对时间。绝对时间跟系统时间改变而改变,这说明可以人为的改变该时间。而相对时间则是固定时间,是从请求到资源的那一刻开始算起。
两个时间可以共存,Cache-Control
优先级更高
协商缓存
协商缓存
是服务器用来确定缓存资源是否可用过期
因为服务器需要向浏览器确认缓存资源是否可用,二者要进行通信,而通信的过程就是发送请求,所以在header
中就需要有专门的标识来让服务器确认请求资源是否可以缓存访问,所以就有了下面两组header
字段:
Etag
和If-None-Match
Last-Modified
和If-Modified-Since
Last-Modify/If-Modify-Since
Last-Modify
当浏览器第一次向服务器请求资源时,服务器会在该资源的请求头中加上Last-Modify
,Last-Modify
是该资源在服务器的最新修改时间,也就是说Last-Modify
记录了该资源的最后一次创建、修改时间,保证服务器给浏览器的资源是最新的。
If-Modify-Since
然后当浏览器再次请求这个资源时,会在请求报文中带上If-Modify-Since
If-Modify-Since
是浏览器上一次请求该资源时返回的Last-Modify
时间,也就是说Last-Modify
和If-Modify-Since
是同一个时间
当服务器收到If-Modify-Since
时间后,会判断这个资源的当前最新修改时间和If-Modify-Since
时间是否相等,相等则说明浏览器缓存的资源已经是最新的了,服务器返回304状态码
告诉浏览器资源已是最新不用更新
不相等则说明在浏览器没有请求的这段时间,这个资源已经进行了修改、更新,浏览器本地缓存的这个资源已经不是最新的了,这时候服务器重新返回该资源的最新版以及最新的Last-Modify
时间。
Etag/If-None-Match
Etag/If-None-Match
和Last-Modify/If-Modify-Since
的处理逻辑一致,通俗讲都是第一次请求给个标识,然后下一次请求再把这个标识传回去,服务器判断资源改变没有,改变了就重新返回,没有改变就返回304
,浏览器继续使用本地缓存。
既然都是一样的处理逻辑,那这两个有什么不同吗?
Etag/If-None-Match
和Last-Modify/If-Modify-Since
的不同
说白了Etag/If-None-Match
就是用来弥补Last-Modify/If-Modify-Since
的不足
- Last-Modified标注只能精确到秒级,如果某些资源在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间;
- 某些资源会被定期生成,有时内容并没有变化,但Last-Modified记录的时间却改变了,导致资源刷新;
- 有可能存在服务器没有准确获取资源的修改时间,或者与代理服务器时间不一致等情形。
Etag是服务器自动生成或者由开发者生成的资源在服务器的唯一标识符,能够更加准确的控制缓存
Etag/If-None-Match
的优先级高于Last-Modify/If-Modify-Since
写在最后
文章如有不足之处请指出,一起学习交流,万分感谢~~~