浏览器缓存你 GET 了吗?

引言

其实,缓存这一块的知识对于普通的只是以快速页面开放的同学来说,我想应该是一知半解。但是,很好地理解缓存地过程可以让我们更好地记忆 HTTP 状态码HTTP 首部字段。正常的浏览器缓存的过程:

  • 询问浏览器内存(Memory Cache)
  • 询问本地磁盘缓存(Disk Cache)
  • HTTP 缓存过程,即强缓存和协商缓存

当然如果是 HTTP/2 还可能会有 Push Cache;并且如果应用中使用了 Service Work 的缓存,本次只讲解 HTTP/1X 中的强缓存和协商缓存

浏览器缓存过程

浏览器缓存过程,它会分为强缓存协商缓存。其实,从它们各自的名词就很容易理解它们各自需要描述的东西。

一、强缓存

描述:即服务端一方设定的可缓存内容,这个过程不需要沟通,只要这个缓存有效,那么你就可以去读取它。

缺点:其实这样简单的理解定义,就可以看出它的弊端,当服务端缓存的资源变了,可是浏览器缓存的资源还有效,那么这个资源的更新就没有即时同步,这无疑是不友好的。
强缓存有两种:Expires 和 Cache-Control。

Expires

我想无论是前端或者后端同学,看到这个单词,应该都很容易的联想到 Cookie 的 Expires,它在 Cookie 中作用就是设置 Cookie 的有效期。同样地,在这里它是 HTTP/1 中用来描述缓存资源有效时间的 HTTP 实体首部字段,它的值为 GMT 时间,由服务端定义好通过响应报文返回给前端。

缺点:其实看到最后一段话,大家应该可以看出它明显的不足,就是由服务端定义好时间,这就会发生服务端和客户端时间不一致的问题。

Cache-Control

Cache-Control 它是 HTTP/1.1 中提出用于缓存的 HTTP 通用首部字段。它则代表资源在一段时间内可以读取缓存,而不用重新请求。而与 Expires 不同,它的值为 max-age=多少 s,并且它还可以搭配一些指令实现一些特定的效果,例如:

  • private,表示 HTTP 请求从浏览器发送到最终的服务器这个过程,只有浏览器缓存,中间任何传递节点不能缓存(代理服务器之类的)
  • public,表示都可以缓存,无论浏览器、服务器或者代理服务器。
  • no-store,表示不需要缓存。
  • no-cache,表示不使用强缓存,使用协商缓存。
  • max-age,表示缓存有效的最大时间,单位为 s。
  • s-maxage,表示代理服务器的缓存有效的最大时间。
  • max-stale,表示浏览器可接受的失效缓存的最大失效时间。
  • max-refresh,表示浏览器可接受的最短更新时间,不过这个时间是当前的 age 加上 max-refresh。

当 Expires 和 Cache-Control 的优先级较高

扫描二维码关注公众号,回复: 9827469 查看本文章

二、协商缓存

描述:即这个缓存的过程需要通过双方的确认,才能决定缓存资源是否可用,可用则返回状态码 304 Not Modified,不可用则返回状态码 200 OK 和更新后的资源。

缺点:因为缓存的最终确定需要浏览器和服务器双方的确定,所以性能较低、耗时较长。

Last-Modified

Last-Modified 是 HTTP/1.0 中用于协商缓存的 HTTP 响应首部字段,它表示该资源的最后修改时间,它会和 If-Modified-Since 一起使用。

这个过程大致是这样的,服务端在响应报文中添加 Last-Modified 首部字段即相应的值(同样是 GMT 时间),然后浏览器在接受响应后,会将资源进行缓存和记录 Last-Modified,在下次请求相同资源的时候添加 If-Modified-Since HTTP 请求首部字段 携带之前记录的 Last-Modified 的值一起发送到服务端,服务端识别到 If-Modified-Since 字段,并与该资源上次修改的时间进行比较,如果相同则返回状态 304 Not-Modified,如果不同则发送状态码 200 OK 以及在报文实体中携带上更新过的资源。

缺点:

  • 在浏览器本地可以修改资源,并且此时该资源对应的 Last-Modified 也会随着变化,那么此时就会造成服务端返回状态码 200 OK 情况和返回没有更新的资源,即这个请求完全没有意义。
  • Last-Modified 无法观察低于秒时的文件的修改,那么这就会造成文件已经更新了,但是服务端却认为它没有更新状态 304 Not-Modified,让浏览器去读缓存,即资源更新不精确。

ETag

ETag 是 HTTP/1.1 中用于协商缓存的 HTTP 响应首部字段,它是由服务端为该资源生成的 Hash,她会和 If-No-Match 一起使用。

它的过程会是这样,服务端在响应报文中添加 ETag 首部字段及对应资源的 Hash,同样地,然后浏览器在接受响应后,会将资源进行缓存和记录 ETag,在下次请求相同资源时通过 If-No-Match HTTP 请求首部字段 携带之前记录的 ETag 的值一起发送到服务端,服务端识别到 ETag 字段,并于该资源此时的 Hash 值进行比较,如果相同返回状态码 304 Not-Modified,如果不同则发送状态码 200 OK 以及在报文实体中携带上更新过的资源。

缺点:

  • ETag 需要服务端计算资源生成 Hash,这个过程无疑是比较慢的,所以性能较低。

当 ETag 和 If-Modified 同时存在时,ETag 的优先级较高

总结

虽然,强缓存和协商缓存只是浏览器缓存过程一部分,但是阅读起来知识点其实不少,如文章开头提到的 HTTP 状态码、HTTP首部字段、以及浏览器请求 URL 的这个过程,都或多或少会涉及到一些。不过,大家在阅读的过程不需要任何负担,其实整个缓存的过程就只有几个单词,前人在定义这些单词的时候,并非随意为之,每一个都有它的意义,这些单词就是我们阅读时的记忆点。所以,大家放平常心从这些单词出发,自然而然就会构建整个缓存的过程在记忆中。

发布了140 篇原创文章 · 获赞 16 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_42049445/article/details/104433246