HTTP缓存

如何缓存

  1. 降低网络上发送HTTP请求的次数,这采用"过期"机制.
    HTTP服务器通过两种实体头(Entity-Header)来实现"过期"机制:Expires头和Cache-Control头的max-age子项
    Expires/Cache-Control控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只是Cache-Control比Expires可以控制的多一些,而且Cache-Control会重写Expires的规则
  2. 降低网络上完整回复HTTP请求包的次数,这采用"确证"机制.
    HTTP服务器通过两种方式实现"确证"机制:ETag以及Last-Modified

相关的Header

Cache-Control:
  • max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
  • s-maxage(单位为s)同max-age,只用于共享缓存(比如CDN缓存),也就是说max-age用于普通缓存,而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖掉max-age和Expires header

    • public 指定响应会被缓存,并且在多用户间共享。如果没有指定public还是private,则默认为public。

    • private 响应只作为私有的缓存,不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。

    • no-cache 指定不缓存响应,表明资源不进行缓存,比如,但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。

  • no-store 绝对禁止缓存,一看就知道如果用了这个命令当然就是不会进行缓存啦~每次请求资源都要从服务器重新获取。
  • must-revalidate指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了。
Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求

Last-modified

服务器端文件的最后修改时间,需要和cache-control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源

Etag

根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改
为什么要使用Etag呢?Etag主要为了解决Last-Modified无法解决的一些问题

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET
  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
  3. 某些服务器不能精确的得到文件的最后修改时间

缓存的过程