HTTP 缓存机制
HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。它可以减少服务器的压力,如果不使用缓存,每次发起请求都要求服务器发送相应数据,很多时候服务器发来的内容并没有发生变化,就会“浪费”服务器带宽。可以在客户端设置缓存, 给缓存加上过期时间,如果期限没到就是用本地缓存的内容。然而常见的 HTTP 缓存只能存储 GET 响应,对于其他类型的响应则无能为力。
缓存的头部
HTTP 相关的缓存头部一般有:
Cache-Control通用的首部,它是缓存控制字段;Expires响应首部,代表资源过期时间;Last-Modified响应首部,表示资源的最新修改时间,由服务器告诉浏览器;If-Modified-Since请求首部,表示资源的最新修改时间,由浏览器告诉服务器。它和Last-Modified是一对,它俩用来做对比;Etag响应首部,用于资源标识,由服务器告诉浏览器;If-None-Match请求首部,缓存资源标识由服务器告诉服务器(就是上一次服务器给的Etag)。它和Etag是一对,它俩用来做对比;
Expires和 Cache-Control 被称为强缓存,而Etag和 Last-Modified 被称之为协商缓存。
除了头部,有些状态码与缓存也有些关系:
200则表示为成功。一个包含例如HTML文档,图片,或者文件的响应。304说明无需再次传输请求的内容,也就是说可以使用缓存的内容。206不完全的响应,只返回局部的信息,常用在断点续传中。
Expires 响应首部很好理解,就是设置一个过期时间,值是一个 http 时间戳,如:
Expires: Wed, 21 Oct 2019 07:28:00 GMT
设置后,当客户端再次发送请求时就会检查 Expires 的过期时间,如果过期了就去向服务端发起请求,没过期就是用本地的缓存。如果不想使用缓存,可以将值设置成 0,即该资源已经过期。
但 Expires 有一个问题,假如缓存时间到了,需要重新向服务端获取数据,而服务端并没有更新内容,这就会造成“浪费”。最好需要一种比较“精确”的方式,当服务端真正更新数据时才让客户端使用新的内容,不然就让它使用缓存。
Last-Modified 和 If-Modified-Since 就是为了解决这个问题的。在客户端第一次请求某个资源时,服务器会发来一个 Last-Modified 头部,他与 Expires 头部的值很像,不过它表示的是资源做出修改的日期和时间。它可以与 Expires 头部一起使用。
当再次发起网络请求时,客户端会向服务器提供一个 If-Modified-Since 请求首部,如果之前响应带有 Expires 头部,会先检查缓存时间到了没,如果没到继续使用,过期了就请求服务器。服务器收到请求首部,拿到 If-Modified-Since 的日期,它是上一次响应首部 Last-Modified 的值,与现在文件的最新修改日期做对比,如果文件修改了,就返回修改后的文件内容和新的 Last-Modified 响应首部,状态码为 200
