强缓存和协商缓存分别是什么?

60 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

一、概述

浏览器缓存主要有以下几个优点:

  • 减少重复数据请求,避免网络再次加载资源,节省流量
  • 降低服务器压力,提升网站性能
  • 加快客户端加载网页的速度,提升用户体验

浏览器缓存分为强缓存和协商缓存,两者有明显的区别:

  • 强缓存从浏览器缓存中获取数据,不需要给服务器发送请求;而协商缓存需要给服务器发请求,由服务器来决定是否使用缓存
  • 强缓存在Chrome中from cache状态码返回的是200,在Fire Fox中 from cache状态码是304;协商缓存如果命中缓存,请求的状态码是304(not modified),有更改返回200

二、请求流程

浏览器在第一次请求后缓存资源,再次请求时,会进行下面两个步骤:

  • 第一步:浏览器获取该资源的header中的信息,根据Response header中的 expirescache-control来判断是否命中强缓存,如果命中强缓存,则直接缓存中获取资源
  • 第二步:如果没有命中强缓存,这次请求会带上IF-Modified-Since或者IF-None-Match,他们的值分别是第一次请求返回的Last-Modified或者Etag,由服务器根据比对来判断是否需要返回新的内容。如果命中缓存,则服务器返回304状态码,并且不会返回资源内容,浏览器则会直接从缓存获取;否则服务器最终会返回资源的实际内容,状态码一般为200,并更新header中的缓存字段

三、强缓存

强缓存是根据返回头中的 Expires 或者 Cache-Control 两个字段来控制,都是表示资源缓存有效期

  • Expireshttp1.0的规范,Cache-Controlhttp1.1的规范,优先级:Cache-Control > Expires
  • Expires 是一个GMT格式的时间点字符串,例如:Expires:Thu, 15 Dec 2022 04:19:22 GMT。这个时间点代表资源失效的时间,如果当前的时间在这个时间点之前,则命中缓存。有一个缺点就是如果服务器和客户端的时间不一致的话会导致缓存混乱
  • Cache-Control 一般常用max-age值来判断,他是一个相对时间,比如:Cache-Control:max-age=3600 表示资源的有效期是3600秒,并且返回头中的Date表示发送的时间,表示当前资源在 Date - Date + 3600秒 内都是有效的。Cache-Control 还可以设置其他值:
    • no-cache 不使用本地缓存。需要使用协商缓存。
    • no-store直接禁止浏览器缓存数据,每次请求资源都会向服务器要完整的资源, 类似于 network 中的 disabled cache
    • public 可以被所有用户缓存,包括终端用户和 cdn 等中间件代理服务器。
    • private 只能被终端用户的浏览器缓存。

四、协商缓存

协商缓存是由服务器来确定缓存资源是否可用。 主要涉及到两对属性字段,都是成对出现的,即第一次请求的响应头带上某个字, Last-Modified 或者 Etag,则后续请求则会带上对应的请求字段 If-Modified-Since或者 If-None-Match,若响应头没有 Last-Modified 或者 Etag 字段,则请求头也不会有对应的字段。

  • Last-Modifined/If-Modifined-Since 都是GMT格式的时间字符串,Response中的Last-Modified标记最后文件修改时间,下一次请求时,Request请求中会带上If-Modified-Since值,改值是服务器返回的Last-Modified的值,在服务器上判断资源是否有变化,如果没有变更则返回304 Not Modified,请求不会返回资源,浏览器直接使用本地缓存。如果资源有变化则返回资源内容。
  • Etag/If-None-Match 值是服务器为每个资源生成的唯一标识串,只要资源有变化这个值就会发生变化。服务器根据文本身算出一个hash值通过Etag返回给浏览器,服务器收到If-None-Match字段判定两者是一致来判断文件是否更改。