wang1dot0 / personal-note

记录工作中遇到的个人觉得比较有意思的小问题
https://github.com/wang1dot0/personal-note
0 stars 0 forks source link

浏览器缓存 #3

Open wang1dot0 opened 5 years ago

wang1dot0 commented 5 years ago

浏览器缓存的作用

加快客户端访问速度 节省带宽 减轻服务端压力

强制缓存 vs 协商缓存

强制缓存是利用http头部中cache-control与expires两个字段控制的,表示缓存资源的时间。浏览器强制刷新会带上Cache-Control:no-cachePragma:no-cache

Expires

这是一个精确到秒级别的GMT时间,表示缓存失效的时间:只要发送请求的时间在失效时间之前,就会用本地缓存。缺点:服务器与客户端时间差别较大时,缓存混乱。

Cache-Control

HTTP1.1协议。 主要利用max-age属性来管理缓存,它是一个相对时间。 其他属性:

no-cache: 不使用本地缓存 no-store: 直接禁止浏览器缓存数据 public: 可以被所有用户缓存,包括终端用户和CDN等中间代理 private: 只能被终端用户的浏览器缓存。 must-revalidate: 强制校验缓存,每次请求发出时,缓存验证字段都会发送到服务器,服务器端会验证请求中的缓存是否过期,若未过期则返回304,使用本地缓存。

Cache-Control与Expires相比有更高的优先级

Pragma头

HTTP/1.0标准下的header属性,请求中包含Pragma头与Cache-Control: no-cache相同,但是响应头不支持该属性,所以不能完全替换HTTP/1.1中的Cache-Control头 作用: 向后兼容HTTP/1.0客户端

协商缓存就是由服务器确定缓存资源是否可用,浏览器与服务器之间通过某种标识协商通信,利用服务器来判断缓存是否可用。 普通刷新就是使用的协商缓存,忽略强缓存。只有在地址栏/收藏夹输入网址的情况下,浏览器才会启用强缓存

Last-Modify与If-Modify-Since

LastModify是弱校验器,因为只能精确到秒。 浏览器第一次请求资源时,服务器返回的header中会加上Last-Modifiy, Last-Modify是标识资源最后的修改时间,为GMT时间。浏览器再次请求该资源时,在请求中会加入If-Modify-Since, 该值为上次请求服务器返回的Last-Modify。服务器收到If-Modify-Since后,根据资源最后的修改时间判断是否命中缓存。

如果命中缓存,则返回304,并且不会返回资源内容,且不会返回Last-Modify。

Etag与If-None-Match

Etag是一种强校验器,对于UA是不透明的。 Etag保证每个资源是唯一的,资源变化会导致Etag变化。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。

Last-Modified不同的是,当服务器返回304 Not Modified的响应时,由于Etag重新生成过,response header中还会把这个Etag返回,即使Etag值没有变化。

Etag与Last-Modify的不同

  1. 一些文件也许会周期性更改,修改时间变化了但是他的内容并不改变,这个时候并不希望客户端认为文件被修改了,而重新GET。
  2. 某些文件的修改非常频繁,秒级别的精度已经不能及时更新,If-Modified-Since不能完成这么细粒度的更新。
  3. 某些服务器不能精确得到文件的Last-Modify。
  4. Etag与Last-Modify同时使用时,服务器优先验证Etag,在Etag校验一致时,才会继续比对Last-Modify
wang1dot0 commented 5 years ago

Vary

只存在于HTTP的响应头中,用来决定是否使用缓存服务器的资源。 当缓存服务器收到一个新的请求,只有当前的请求与原始的请求头跟缓存中的响应头里的Vary都匹配时,才能使用缓存的资源。 用途:有利于缓存服务器提供服务的多样性。如将Vary:User-Agent后,可以区分请求是来自移动客户端还是PC客户端。