前言: 浏览器在请求资源时,比如图片,文本,HTML文件,会向服务器去发送请求来获取对应的资源,但是像一些不怎么更改的资源,比如logo,就可以缓存下来,比如百度一下的logo,基本是不需要变化的,并且它每次请求图片的时间基本都是0ms。这是怎么做到的呢?
这就要说到强缓存和协商缓存了:
强缓存
强缓存是浏览器在第一次请求资源时,响应头中有一个'Cache-Control': 'max-age'=86400,意思就是在86400秒(一天)内,浏览器再请求这个资源时,在这个时间内,就不要向服务器去发请求了,而是在缓存中寻找。
比如百度的logo被强缓存了十年
实现方式:
服务端设置响应头:
- 'Cache-Control': 'max-age'=86400
缺点:
- 资源命名没有发生改变,但是文件发生改变,浏览器不会更新
- 无法缓存输入url之后的get请求。(这里可以向面试官去扩展浏览器输入url到渲染页面的流程)
协商缓存
上面提到了百度的logo被强缓存了十年,那每当有节日的时候百度logo又会改变,这是怎么做到的呢?
这就用到了协商缓存:
协商缓存是浏览器在每一次请求资源时,都会向服务器去询问是否要从服务器请求资源,如果不用向服务器请求资源则会从缓存中过去,这就是协商缓存。
具体实现方式是:
- 浏览器第一次请求资源时,服务区返回资源,并根据这个资源生成一个etag值,将etag值放到响应头中返回,以后浏览器在每一次请求时都会将这个etag值放到If-None-Match中,服务器接收到后会拿这个etag值与所请求资源的etag值进行对比,如果没有发生更改,就返回304,告诉浏览器资源没有发生改变,使用缓存中的资源(不返回所请求的资源),如果etag值不同,则返回200,并且返回所请求的资源
比较大一点的资源就放在磁盘缓存中,小一点的资源放在了内存缓存中。
强缓存的优先级高于协商缓存,当两者同时存在时,且强缓存有效期未过,则会使用强缓存而不使用协商缓存