# http的缓存类型

强缓存: 浏览器直接从本地缓存中获取数据,不与服务器进行交互

协商缓存: 浏览器发送请求到服务器,服务器判定是否可以使用本地缓存

  • 强缓存和协商缓存最终使用的都是本地缓存;区别在于是否与服务器进行交互

图解:
image

缓存相关header:

类型 含义
Expires 响应头 代表该资源的过期时间,由服务器告诉浏览器
Cache-Control 请求/响应头 缓存控制字段,精确控制缓存策略
If-Modified-Since 请求头 资源最近修改时间,由浏览器告诉服务器
Last-Modified 响应头 资源最近修改时间,由服务器告诉浏览器
If-None-Match 请求头 缓存资源标识,由浏览器告诉服务器
Etag 响应头 资源标识,由服务器告诉浏览器

配对使用的字段:

  • If-Modified-Since 和 Last-Modified
  • If-None-Match 和 Etag

# 强缓存

由Expires 和 Cache-Control两个字段来判断缓存是否过期:
1.查看缓存是否有Cache-Controls-maxagemax-age指令
2.如果有,使用响应报文生成时间Date + s-maxage/max-age获得过期时间,再与当前时间进行比较
3.如果没有,比较Expires的过期时间和当前时间

Cache-Control常用指令

  • no-cache:含义是不使用本地缓存,需要使用协商缓存,需要先与服务器确认缓存是否可用
  • no-store:禁用缓存
  • public:表明其他用户也可以使用缓存,适用于公共缓存服务器的情况
  • private:表明只有特定用户才能使用缓存,适用于公共缓存服务器的情况

# 协商缓存

缓存过期了,但是不知道服务器的资源是否改变,所以需要与服务器协商判断:
浏览器:
1.判断缓存是否有ETag或者Last-Modified字段
2.如果有,就发起一个http请求,在请求头中添加If-None-Match(如果ETag存在的话) 和If-Modified-Since(如果Last-Modified存在)字段
3.如果没有,发起一个http请求,服务器直接返回资源
服务器:
1.浏览器如果同时发送了If-None-MatchIf-Modified-Since字段,服务器只要比对 If-None-MatchETag的内容是否一致即可 2.如果一致,服务器认为缓存可用,返回304状态码,浏览器直接读取本地缓存
3.如果不一致,服务器返回其他状态码,并返回所请求资源

If-None-MatchETag

这两个值都是服务器为每份资源分配的唯一标识字符串

  • 浏览器首次请求资源,服务器响应时会在响应报文头加入ETag字段。资源更新ETag值也会更新
  • 浏览器再次请求资源,就会带上If-None-Match字段,它的值就是上次响应报文的ETag
  • 服务器进行If-None-MatchETag的比对......

If-Modified-SinceLast-Modified

这两个值都是GMT格式的时间字符串

  • 浏览器首次请求资源,服务器响应时会在响应报文头加入Last-Modified字段,表示最后一次修改时间
  • 浏览器再次请求资源,就会带上If-Modified-Since,它的值就是上次响应报文的Last-Modified
  • 服务器进行If-Modified-SinceLast-Modified的比对.....

但是与ETag不同的是:比对结果是资源未更新可以使用本地缓存到时候,响应头不会添加Last-Modified字段

ETag对比Last-Modified的优点

主要是能解决几个Last-Modified难以解决的问题:

  • If-Modified-Since的时间粒度是秒级的,如果文件是频繁修改的话,无法精准判断
  • 有些文件只改了修改时间,却没改内容
  • 有些服务器不支持精确获取文件最后的修改时间

Last-ModifiedETag是可以一起使用的,但是服务器优先验证ETag