聊一聊HTTP缓存机制

1,169 阅读2分钟

前言

  • 在说缓存之前先简单说一下HTTP报文。HTTP报文是在HTTP应用程序之间发送的数据块。报文的结构由起始行、头部(header)和主体(body)组成。报文的类型又有请求报文和响应报文。

缓存

  • 当浏览器第一次向服务器请求资源时会去询问服务器这个资源该不该缓存,用什么方法缓存。假设服务器同意浏览器缓存,并告诉浏览器一个资源失效时间,这个时间存放在Expires中如:Mon,10 Dec 1990 02:25:22GMT。那么这个资源在这个时间之前都能使用。那么有一个问题是:客户端的时间是可以被修改的,而且客户端和服务器时间未必一致。
  • 既然返回一个绝对时间不好用,那么服务器就返回一个相对时间好了,这个时间在Cache-Control:max-age=300单位是秒(s)。现在好了300秒内这个资源就不会过期。那么有一种可能是300秒后我再次去服务器拿这个资源发现资源并没有被改变过,服务器又再次返回了同样的资源给我,这样的话就浪费了一次带宽。其实可以返回一条信息给浏览器表明缓存资源可以继续使用。
  • 现在回到浏览器第一次请求的时候,服务器响应头中多了一个ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q"。这个ETag是服务器根据资源计算出的唯一标识,通常配合max-age使用。当时间过期以后浏览器会将标识放在请求头中的If-None-Match,服务器收到请求以后会拿请求中的标识与服务器根据资源计算的Etag进行比较,若一致则返回响应头其中包含状态码304。不一致就返回新的资源。但是在分布式系统中每个机器生成的ETag不一样。
  • 既然ETag也不是那么的靠谱,那么服务器第一次返回时在响应头中又加了一个字段Last-Modified。当资源过期时浏览器发现资源有Last-Modified,然后发请求时便在请求头增加了一个字段If-Modified-Since表示发送的请求时间,服务器拿到这个时间与资源的最后修改时间比较,如果修改时间比较新那么返回新的资源,否则返回Http 304。

补充

1.当ExpiresCache-Control:max-age同时存在时max-age的优先级高。
2.[Last-Modified,If-Modified-Since]和[ETag、If-None-Match]经常会放在一起使用。