测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)

前言 最近一个好奇的测试同学问我,你们前端开发完成后,每次都让我们清缓存或者Ctrl+f5强制刷新,我能不能每次不用强制刷新,就能看到你们更新的内容呢。我说是可以做到的,我来跟你讲讲浏览器的缓存策略。我相信应该有不少的同学在工作中都会遇到这种情况,让你的测试同学清缓存等。
缓存 浏览器缓存是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘或内存中显示文档,这样就可以加速页面的阅览。
浏览器缓存主要有两类:强缓存:cache-controlExpires 缓存协商:Last-modifiedEtag
所有的缓存策略都是通过http header里设置的。
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

强缓存 当浏览器去获取资源的时候,不给服务器发请求,直接从缓存中读取。
Expires(过期时间)
Expires(缓存过期时间)是http1.0的产物,用来指定资源的到期时间,是服务端返回的时间点。
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

从上面图我们可以看出在Expires: Thu, 20 Jan 2022 07:50:17 GMT在这之后会过期,请求改资源不会从缓存中获取。
缺点: 时间的判断是通过本地判读的,如果本地时间调大了,缓存可能会失效。
Cache-Control
Cache-Control是http1.1控制缓存的重要字段,如果Cache-Control在,它的优先级会比Expires高。常用的值如下

名称 描述
public 表示可以被客户端和代理服务器缓存
private 表示只可以被客户端缓存
max-age=30 单位为秒(s), 表示30s之内,从缓存中获取
s-maxage=30 max-age一样,表示只在代理中生效
no-sotre 不缓存任何响应
no-cache 资源被缓存,但马上失效,下次请求会通过协商缓存验证资源是否过去
max-stale=30 在30s之内,缓存过期也从缓存中读取
协商缓存 协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有两组配合使用:
  • Last-ModifiedIf-Modified-Since
  • EtagIf-None-Match
Last-Modified和If-Modified-Since
浏览器在第一次访问资源的时候,服务器返回资源的同事,会在Response header中添加Last-Modified的key,表示该资源最后修改时间,浏览器接收后缓存文件header,下次请求该资源,浏览器会检测到有Last-Modified这个请求头,于是在请求中会添加If-Modified-Since这个请求头,值就是之前Last-Modified中的值。服务器收到请求后,会根据If-Modified-Since中的值去判断资源是否更新。
如果值相等,就返回304状态码和空的响应体,浏览器收到后会通过缓存获取。可以看下图
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

如果不相等,就返回内容和200的状态码。
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

EtagIf-None-Match
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到Request header里的If-None-Match,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。
如果值相等,就返回304状态码和空的响应体,浏览器收到后会通过缓存获取。可以看下图
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

如果不相等,就返回内容和200的状态码。
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

注意ETag和If-None-Match优先级高于Last-Modified和If-Modified-Since,同时存在则只有ETag和If-None-Match生效。
应用部署设置规则 我们知道了浏览器的缓存之后,在常见的web开发中我们应该怎么设置呢。
现在大多数的应用是通过webpack打包的,打包生成的资源名称会带上hash值。下面是打包后的文件
测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)
文章图片

我们可以遵循之下规则
  • index.html入口文件不加强制缓存,设置成协商缓存
  • js 资源在线上环境可以设置成强缓存。
因为我们每次打包之后,入口文件会有变化,所以协商缓存会失效,会重新从服务器获取新的资源。而对应的js资源有hash的变化,所以有变化,会从服务器中获取。
结束语 浏览器的缓存策略,我们就说到这了,快来学习下,跟你的测试小伙伴说一说。
如果你觉得该文章不错,不妨
1、点赞,让更多的人也能看到这篇内容
2、关注我,让我们成为长期关系
【测试同学问我为什么每次让我清缓存(聊聊浏览器的缓存)】3、关注公众号「前端有话说」,里面已有多篇原创文章,和开发工具,欢迎各位的关注,第一时间阅读我的文章

    推荐阅读