一文弄懂强缓存与协商缓存

146 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

前言

大家好,我是小阵,身为一个前端小菜鸟,总是有一个飞高飞远的梦想,因此,每点小成长,我都想要让它变得更有意义,为了自己,也为了更多值得的人

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

为什么要有浏览器缓存?

随着网页内容越来越丰富,h5的的适用范围越来越广泛,hybrid方案的大规模流行,浏览器承担着越来越重的交换资源的任务,为了让交换资源不那么繁重,浏览器就有了相应的缓存方案。

浏览器缓存的出现,显而易见的有了以下优点:

  • 减少客户端与服务端的请求次数
  • 减少服务器负担
  • 提高了用户的使用体验

什么是浏览器缓存

浏览器缓存并不一定要将资源缓存再浏览器,浏览器只要实现一套规则帮助客户端和服务端进行缓存即可。

也就是,客户端通过浏览器要认识服务端的缓存方案,服务端的缓存相应规则也有配套的浏览器请求来触发即可。

围绕这一套规则实现了浏览器的强缓存和协商缓存,这两种方案分别针对两种不同的场景。

怎样使用浏览器缓存

上面说了浏览器缓存分为强缓存和协商缓存,顾名思义,强缓存就是符合规则的缓存资源永远留存,也就是不会再刷新新资源,协商缓存则是需要客户端和服务端进行交互协商看下是否需要更新资源或是依然走老的缓存资源。

下面详细分析两种缓存的情况

强缓存

  • 强缓存通过ExpiresCache-Control字段来触发

    • Expires包含在响应头中

      • Cache-Control的优先级大于Expires,如果存在Cache-Control,则忽略Expires
      • Expires设置的是绝对时间,是一个固定的时间点。如果是0则表示过期,正常时间则正常判断是否可以走缓存
    • Cache-Control既可以在请求头中,也可以在响应头中

      • 在请求头中

        • Cache-Control: max-age=<seconds>允许资源缓存secondes秒。其中seconds则是可设置的缓存时间,是个相对时间,相对于请求时的时刻。
        • Cache-control: no-cache表示忽略强缓存,直接走写上缓存规则
        • Cache-control: no-store不做任何缓存
      • 在响应头中

        • 同样存在max-ageno-cacheno-store,且跟上面用法一致
        • Cache-control: public表明可以被代理服务器(如nginx或其他高防服务器)或浏览器缓存
        • Cache-control: private表明只允许将缓存资源缓存在浏览器
      • Cache-Control的多个指令可以联合使用,例如:Cache-Control:public, max-age=31536000

如果设置有Cache-Control: max-age=xxx或者Expirer=xxx则浏览器会判断该浏览器是否处于缓存周期内,如果在缓存周期,且允许浏览器本地缓存,则从浏览器取缓存,否则去代理服务器或服务器取缓存。

如果该资源未在缓存周期内,则查看是否符合协商缓存规则。

协商缓存

  • 协商缓存通过响应头的EtagLast-Modify或请求头的If-None-MatchIf-Modify-Since来触发

    • 响应头

      • Etag表示资源的唯一值,如果资源发生变化,则该值也会变化
      • Last-Modify表示资源的最后更新时间
      • Etag的优先级大于Last-Modify,只有Etag相同才会比对Last-Modify
    • 请求头

      • If-None-MatchEtag字段相对应,用来协商时服务端比对资源内容是否修改
      • If-Modify-SinceLast-Modify字段相对应,用来协商时比对资源最后的修改时间
  • 协商缓存是在强缓存未生效时触发,浏览器携带请求头的If-Modify-SinceIf-None-Match字段到服务端,服务端根据业务需求来判断If-Modify-SinceIf-None-Match,跟现有资源做比较,如果发生变化,则重新拉取新资源,否则返回缓存资源,并且response status为304

我们可以看到,无论是Last-ModifyEtag单独拿出一个就可以判断文件是否变化,那又为什么要同时出现呢?

这个是因为一些特殊的业务场景,比如:

一些文件会周期性的变化,比如定期拉取一些数据,但是可能文件内容不会变化,这个时候就可以根据Etag字段来进行判断

再比如:

某些文件会在很短的时间内变化,比如服务器某一刻峰值检测,此时每一个极短的时间内都会有数据变化,但是时间因为差距太小导致某些浏览器没办法识别到精度,从而导致文件内容变化了,但是Last-Modify字段却没有变化。

因此,通常要两个字段配合使用。

以上,就是强缓存和协商缓存的所有内容。

结语

如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~

文章如有错误或不严谨之处,还望指出,感谢感谢!!!

加油!

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」