http 基础知识之缓存控制

哪有什么来日方长,挥手便是人走茶凉。

 

由于链路漫长,网络时延不可控,浏览器使用HTTP获取资源的成本较高。
所以,非常有必要把“来之不易”的数据缓存起来,下次再请求的时候尽可能地复用。这样,就可以避免多次请求-应答的通信成本,节约网络带宽,也可以加快响应速度。

基于“请求-应答”模式的特点,可以大致分为客户端缓存和服务器端缓存,因为服务器端缓存经常与代理服务“混搭”在一起,所以今天我先讲客户端——也就是浏览器的缓存。

 

服务端缓存

缓存流程

  1. 浏览器发现缓存无数据,于是发送请求,向服务器获取资源;
  2. 服务器响应请求,返回资源,同时标记资源的有效期;
  3. 浏览器缓存资源,等待下次重用。

 

Cache-Control 字段 max-age 标识:生存时间,时间的计算起点是响应报文的创建时刻(即Date字段,也就是离开服务器的时刻),而不是客户端收到报文的时刻,也就是说包含了在链路传输过程中所有节点所停留的时间。

比如,服务器设定“max-age=5”,但因为网络质量很糟糕,等浏览器收到响应报文已经过去了4秒,那么这个资源在客户端就最多能够再存1秒钟,之后就会失效。

“max-age”是HTTP缓存控制最常用的属性,此外在响应报文里还可以用其他的属性来更精确地指示浏览器应该如何使用缓存:

  • no-store:不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面;
  • no-cache:它的字面含义容易与no-store搞混,实际的意思并不是不允许缓存,而是可以缓存,但在使用之前必须要去服务器验证是否过期,是否有最新的版本;
  • must-revalidate:又是一个和no-cache相似的词,它的意思是如果缓存不过期就可以继续使用,但过期了如果还想用就必须去服务器验证。

具体的过程如下图所示

 

客户端缓存

当点击浏览器刷新按钮的时候,浏览器会在请求头里加一个“Cache-Control: max-age=0”,所以浏览器不适用本地缓存,直接去服务器请求最新的数据。

Ctrl+F5的“强制刷新”,它其实是发了一个“Cache-Control: no-cache”,含义和“max-age=0”基本一样,就看后台的服务器怎么理解,通常两者的效果是相同的。

 

浏览器的缓存究竟什么时候才能生效呢?
别着急,试着点一下浏览器的“前进”“后退”按钮,再看开发者工具,你就会惊喜地发现“from disk cache”的字样,意思是没有发送网络请求,而是读取的磁盘上的缓存。

 

条件请求

浏览器用“Cache-Control”做缓存控制只能是刷新数据,不能很好地利用缓存数据,又因为缓存会失效,使用前还必须要去服务器验证是否是最新版。

浏览器可以用两个连续的请求组成“验证动作”:先是一个HEAD,获取资源的修改时间等元信息,然后与缓存数据比较,如果没有改动就使用缓存,节省网络流量,否则就再发一个GET请求,获取最新的版本。
但这样的两个请求网络成本太高了,所以HTTP协议就定义了一系列“If”开头的“条件请求”字段,专门用来检查验证资源是否过期,把两个请求才能完成的工作合并在一个请求里做。而且,验证的责任也交给服务器,浏览器只需“坐享其成”。
条件请求一共有5个头字段,我们最常用的是“if-Modified-Since”和“If-None-Match”这两个。需要第一次的响应报文预先提供“Last-modified”和“ETag”,然后第二次请求时就可以带上缓存里的原值,验证资源是否是最新的。
如果资源没有变,服务器就回应一个“304 Not Modified”,表示缓存依然有效,浏览器就可以更新一下有效期,然后放心大胆地使用缓存了。

 

posted @ 2021-12-08 08:57  方达达  阅读(8)  评论(0编辑  收藏  举报