浏览器缓存

114 阅读3分钟

浏览器缓存

可以被缓存的资源:静态资源,如 js、css、img。

  • 缓存存入:浏览器每次拿到返回结果,都会将该结果和缓存标识存入浏览器缓存中。
  • 缓存读取:浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识。

强制缓存/强缓存

强制缓存是向浏览器缓存中查找该请求结果,不需要发送请求到服务端。

根据请求头Cache-ControlExpires判断是否命中强缓存,其中Cache-Control优先级比Expires高。

  • Cache-Control(HTTP1.1)中

    • max-age:最大生命周期,缓存内容将在该周期后失效,单位是秒。如Cache-Control: max-age=3153600
    • no-cache:可以缓存,但需要通过协商缓存向服务器验证缓存是否可用。
    • no-store:所有内容都不会缓存。
  • Expires(HTTP1.0):服务器返回数据的到期时间。当再次请求时的请求时间小于该时间,可使用强缓存。受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

分为以下情况:

  1. 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求,跟第一次发起请求一致。
  2. 存在该缓存结果和缓存标识但该结果已过期失效,强制缓存失效,使用协商缓存进行验证。
  3. 存在该缓存结果和缓存标识且该结果尚未失效,强制缓存生效,直接返回该结果,展示灰色的200状态码,看到from cache字样。

协商缓存

需要对比判断是否可以使用缓存。浏览器第一次请求时,服务器将缓存标识数据一起发送给客户端,客户端将它们备份到缓存中。再次请求时,客户端将缓存标识发送给服务器,服务器根据此标识判断。分为以下情况:

  • 协商缓存生效,返回304
  • 协商缓存失效,返回200和请求结果

响应头ETag:相当于指纹,该资源在服务器的唯一标识,资源变化则ETag变化,跟最后修改时间没有关系。

请求头If-None-Match:再次请求该资源时,包含该请求头,值为服务器上次返回Etag值。询问服务器该资源是否有变动。变动则返回200,传输响应体;未变化则返回304,传输响应头。

响应头Last-Modified:客户端第一次请求资源时,服务器返回该响应头,该时间标识资源的最后修改日期和时间,精确到秒级。

请求头If-Modified-Since:再次请求该资源时,包含该请求头,值为服务器上次返回Last-Modified值,询问服务器在该日期后资源是否有更新。更新则返回200,传输响应体;未更新则返回304,传输响应头。

其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

两者区别

两者可以同时存在,强缓存的优先级高于协商缓存。

强缓存不经过服务器,可直接使用;协商缓存需要经过服务器,询问是否可使用缓存,若可使用则状态码为304。

实际缓存场景

  • 不需要缓存的资源。Cache-Control: no-store
  • 频繁变动的资源。Cache-Control: no-cache + ETag
  • 代码文件。Cache-Control: max-age + ETag + 策略缓存,文件名变化则下载新的资源。

三种刷新操作对浏览器缓存的影响

  • 正常操作:如地址栏输入 url、跳转链接、前进后退等。强制缓存、协商缓存都有效。
  • 手动刷新:如f5、点击刷新按钮、右键菜单刷新。强制缓存失效,协商缓存有效。
  • 强制刷新:ctrl + f5、shift+command+r。强制缓存、协商缓存都失效。