能够帮助服务器提高并发性能,很多资源不需要重复请求直接从缓存中获取

缓存步骤

1、客户端向服务器发送请求,请求资源;
2、服务器返回资源,并通过响应头决定缓存策略;
3、客户端根据响应头的策略决定是否缓存资源;
4、客户端再次向服务器请求资源时,客户端先去检查上次缓存的资源,根据策略的不同、是否过期等判断是直接读取本缓存还是与服务器写上缓存。

强制缓存

直接从浏览器缓存查找资源,并根据资源的缓存规则来决定是否使用该缓存的过程

是否使用强制缓存主要由两个响应头字段控制:Expires 和 Cache-Control;
如果没有这两个标识字段,则直接从服务器获取资源(跟第一次发起请求一致)。

Expires

Expires: Wed, 11 May 2018 07:20:00 GMT

Expires是HTTP/1.0提出的⼀个表示资源过期时间的header,它描述的是⼀个绝对时间,由服务器返回;
Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

Cache-Control

Cache-Control: max-age=315360000

Cache-Control是HTTP/1.1提出的,表示的是相对时间,当两者同时出现,则以Cache-Control为准,其优先级较高。
目前主流做法是使用Cache-Control控制缓存,除了max-age控制过时时间外,还有一些其他字段:

  • Cache-Control: public 可以被所有⽤户缓存,包括终端和CDN等中间代理服务器
  • Cache-Control: private 只有客户端可以缓存,Cache-Control默认值
  • Cache-Control: no-cache 先缓存本地,但是是否使用缓存则需要经过协商缓存来验证决定
  • Cache-Control: no-store 不会产⽣任何缓存,包括协商缓存

协商缓存

强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

如果缓存和服务端资源的最新版本是一致的,那么就⽆需再次下载该资源,服务端直接返回304 Not Modified 状态码;如果服务器发现浏览器中的缓存已经是旧版本了,那么服务器就会把最新资源的完整内容返回给浏览器 状态码就是200 Ok。

控制协商缓存的响应头字段为:Last-Modified/If-Modified-Since 和 ETag/If-None-Match
其中ETag/If-None-Match的优先级高于Last-Modified/If-Modified-Since

Last-Modified/If-Modified-Since

客户端⾸次请求资源时,服务器会把资源的最新修改时间Last-Modified:Thu, 19 Feb 2019 08:20:55 GMT 通过响应头返回给客户端。当再次发送请求时,客户端将服务器返回的修改时间放在请求头 If-Modified-Since:Thu, 19 Feb 2019 08:20:55 GMT 发送给服务器,服务器再跟服务器上的对应资源进⾏⽐对,如果服务器的资源更新,那么就返回最新的资源,此时状态码是200;当服务器资源跟客户端的请求头的时间⼀致,说明客户端的资源是最新的,返回304状态码,表示客户端直接⽤缓存即可。

ETag/If-None-Match

ETag的流程与Last-Modified是类似的,区别就在于ETag是根据资源内容进⾏hash,⽣成⼀个信息摘要,只要资源内容有变化,这个摘要就会发⽣巨变。通个这个摘要信息⽐对,即可确定客户端的缓存资源是否为最新,⽐Last-Modified 的精确度更⾼。
image.png

缓存流程

总结

强制缓存优先于协商缓存,若强制缓存生效则直接使用缓存,若不生效则进行协商缓存,协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。