HTTP缓存

2020-09-11  本文已影响0人  壹豪

  客户端发出HTTP请求之后,客户端返回的响应头中可以用Pragma、Expires和Cache-Control字段表示是否使用http缓存,为什么需要HTTP缓存呢,当你多次请求同样的数据时,会产生很多不必要的浪费,因此用缓存之后只需要把数据存储在客户端本地,在需要的时候直接从本地调用即可

public 和 private 的选择

  如果你用了CDN,你需要关注下这个值。CDN厂商一般会要求Cache-Control的值为public,提升缓存命中率。如果你的缓存命中率很低,而访问量很大的话,可以看下是不是设置了private,no-cache这类的值。如果定义了max-age,可以不用再定义public,它们的意义是一样的。

no-cache 缓存检验

  当使用 no-cache 对比缓存时,HTTP 响应会返回 Last-Modified 和 Etag 这两个字段,服务端返回数据时,会通过 Last-Modified 把数据的最终修改时间返回到客户端。
过程如下:
服务端响应头:Last-ModifiedEtag,可能还有 ExpiresCache-Control
客户端请求头:If-Modified-SinceIf-None-Match

  1. 客户端请求一个页面 A
  2. 服务器返回页面 A,并在给A加上 Last-Modified、ETag 、Expires 和
    Cache-Control: no-cache max-age = xxxx
  3. 客户端展现该页面,并将页面连同这些重要的请求头数据一起存入缓存。
  4. 客户再次请求页面 A,根据 max-age 判断是否数据是否还有效,如果有效就直接从内存中读取,如果失效则将上次请求时服务器返回的 Last-Modified、ETag 转成 If-Modified-Since、If-None-Match 传递给服务器。
  5. 服务器根据 If-Modified-Since、If-None-Match 来判断该页面自上次客户端请求之后是否被修改,如果没有被修改则直接返回304状态码和一个空的响应体,如果修改了则返回200状态码和新的页面 A。
第一次请求数据 max-age

缓存命中顺序

  1. 最先的ExpiresCatch-Control
    Expires:客户端和服务端绝对时间
    Catch-Control(优先级更高):客户端本地计数比较
  2. 其次Last-ModifiedIf-Modified-Since
    Last-Modified:服务端时间
    If-Modified-Since:客户端时间
    缺点:
    (1)服务端有时候和客户端时间不同步
    (2)有时候一秒内改几次
    (3)有时候服务端资源变化了但是Last-Modified没改
  3. 然后EtagIf-None-Match(优先级高于2)
    Etag(entity tag):服务端通过对资源进行特殊编码生成的唯一校验码,资源变化都会导致ETag变化
    If-None-Match:服务端上次传来的Etag

浏览器请求时的大致过程描述如下:

浏览器发出http请求前,先根据Cache-Control和Expired 字段判断缓存是否过期(两个字段同时存在的情况下,根据Cache-Control判断,该字段不存在时根据Expired判断)。如果没有过期,浏览器不发出http请求,直接从硬盘缓存中读取资源;如果已过期,则进行第2步逻辑;

向服务器发出http请求,其中request headers上会携带If-none-match和If-Modified-since字段,服务器收到请求后,会将If-none-match字段和本地的资源的ETag进行比较,如果二者不相等,则资源已更新,会返回200状态码和资源数据,响应头也会带上最新的资源ETag;如果二者相等,则命中缓存,返回304,浏览器收到响应后会读取本地缓存资源。如果If-none-match字段不存在,服务器会根据if-Modified-since字段进行比对资源的最后修改时间,处理逻辑基本和If-none-match一致。


参考:
[1].彻底理解浏览器缓存机制
[2.]第7题-浏览器缓存命中策略


上一篇 下一篇

猜你喜欢

热点阅读