June 18, 2018 4:01 PM
目录
HTTP缓存的目的是客户端或中介(代理服务器,CDN等)重用已获取的资源能够有效的提升网站与应
用的性能。Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间。
所有通过HTTP协议从服务器获取数据的节点都可看做服务的客户端,但是通过服务器和终端客户端之间是有第三者(例如代理服务器),即HTTP缓存机制是覆盖所有从HTTP服务器获取数据的客户端。
公用缓存:
公用缓存是指缓存的数据是公用的,供多个客户端取用,最为典型的就是CDN的缓存。
私有缓存:
私有缓存是指缓存的数据是私有的,只供单个客户端使用,最为典型的就是浏览器的缓存。
HTTP协议对缓存机制的控制是通过 HTTP请求头和响应头来实现的,其中,请求头来自客户端,响应头来自服务器。也就是说,客户端和服务器之间通过HTTP缓存相关的头部来进行协商当前资源的缓存策略。
当HTTP响应被缓存在客户端后,当获取缓存内容时,客户端会比较当前的请求和被缓存内容的Key是否一致,以此判断是否使用缓存(如不使用,则请求服务器)。
Key通常是由一系列关键字组成的字符串,主要包括:
协议、协议版本、域、端口、路径、请求头字段、Cookie
上面列出的是常用的Key可能的关键字,但是每个客户端的Key都是由自己决定的,在缓存协商中,服务器不会告诉客户端如何去匹配缓存。不同的浏览器/CDN/代理服务器可能会使用不同的Key。
HTTP 1.0时代的缓存特别简单,它定义了两个头字段来进行缓存协商。
Pragma : 这个字段只有一个值(no-cache);当使用此字段时,表示禁用缓存。
Expires : 这个字段也只有一个值,缓存过期时间,它是一个绝对的时间值,例如 Wed, 31 May 2017 03:21:09 GMT ,当系统时间大于这个时间,则缓存过期了,不能使用。
场景 :
HTTP 1.1缓存机制较1.0版本比较复杂一些 ,但是设计却更加巧妙。1.1版本添加了新鲜度验证机制,通过资源的Etag(由资源的字节计算出来的key)或最近修改时间来验证资源是否和服务器一致,以此判断是否使用缓存和更新缓存信息。注意,新鲜度验证是很小的网络通信,若是验证失败,服务端才会返回完整的资源。
HTTP1.1用于缓存协商的头字段分为两类,一类是定义缓存协商的头,一类是用于验证缓存是否有效的头。
其中,定义缓存协商的头只有一个 Cache-Control ,此字段的值非常多。此字段的某些值可同时运用于请求和响应。
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached
Etag
Last-Modified
If-Match
If-None-Match
If-Modified-Since
If-Unmodified-Since
Note: HTTP1.1 缓存头详尽信息查阅mdn和rfc文档
https://tools.ietf.org/html/rfc2616
目前大多数服务器都会同时定义HTTP1.0/1.1缓存,目的是向下兼容浏览器。
当HTTP1.0内部缓存头冲突,1.1内部缓存头冲突,1.0和1.1缓存头冲突时,定义的缓存策略有效规则为: