主要分为:浏览器缓存、http缓存
其中http缓存是web缓存的核心,最难懂也是最重要的一部分。
浏览器缓存,如localStorage,sessionStorage,cookie等等。这些功能主要用于缓存一些必要的数据,比如用户信息,需要携带给后端的参数。(一般只能保存5M左右的数据,多了不行)
所以接下来,我们的重点将围绕http缓存展开。
可以解决的问题:
存在的缺点:
http缓存又分为两种:
简称强缓存。如果浏览器判断请求的目标资源有效命中强缓存,如果直接命中,则可以直接从内存中读取目标资源,无需于服务器做任何通讯。
Expires的作用是,设定一个强缓存时间,在此时间范围内,则从内存或磁盘中读取缓存返回。
但是Expires已经被废弃了!对于强缓存来说,Expires已经不是实现强缓存的首选。
因为Expires判断强缓存是否过期的机制是:获取本地时间戳,并对比先前拿到资源文件的Expires字段做比较,这里就存在一个巨大的bug:如果我的本地时间不准怎么办?
对,Expires太过于依赖本地时间,如果本地时间与服务器时间不同步,就会出现资源无法被缓存或者资源永远被缓存的情况。所以,Expires字段几乎不被使用了。在现在的项目中,我们并不推荐使用Expires,强缓存功能通常使用cache-control字段代替Expires。
没想到吧,说了半天,结果是给废弃的东西。
Cache-control完美解决了Expires本地时间的bug。
Cache-control的使用方法很简单,只要在资源的相应头上写上需要缓存多久就好了:
res.writeHead(200,{
'Cache-Control':'max-age=10'
});
从资源第一次返回的时候开始,往后的10s中内如果资源在此请求,则从缓存中读取。
Cache-Control:max-age=N,N就是需要缓存的秒数。从第一次请求资源的时候开始,往后N秒内,资源若再次请求,则直接从磁盘(或内存中读取),不与服务器做任何交互。
Cache-control中max-age后面的值上一个滑动时间,从服务器第一次返回该资源开始倒计时,所以不需要对比客户端与服务器之间的时间,也就解决了Expires的巨大bug。
Cache-control的属性:
⚠️注意:public与private互斥,默认为private;max-age与s-maxage不互斥,可以一起使用
协商缓存的内容会有点绕,我们仔细看看。
过程:
last-modified字段Cache-control:no-cache这个过程缺一不可。
还没结束,到这里还不能实现协商缓存。
当客户端读取到last-modified的时候,会在下次请求标头中携带一个字段If-Modified-Since,而这个请求头中的If-Modified-Since就是服务器第一次修改时候给他的时间。那么之后每次对该资源的请求,都会带上If-Modified-Since这个字段,而服务端需要拿到这个时间并再次读取资源的修改时间,让两者做对比决定上读取缓存还是返回新的资源。
使用以上方法的协商缓存存在两个非常明显的bug,这两个bug都是基于文件是通过对比修改时间来判断是否内容更改的。
为了解决这两个bug,从http1.1开始新增了一个头信息,ETag,顶住!!马上就顺通了!
ETag就是将原先协商缓存的比较时间戳的形式 -> 比较文件指纹
文件指纹:根据文件内容计算出的唯一哈希值,一旦内容改变哈市值随之改变,指纹也改变。
过程: