文章首发于我的个人博客:https://blog.fstars.wang/2019/12/04/HTTP%E7%BC%93%E5%AD%98%E7%9B%B8%E5%85%B3%E5%A4%B4%E5%AD%97%E6%AE%B5/
简单说说 HTTP 协议中缓存相关的头字段,本文的形式更接近于读书笔记,进行了内容的浓缩。
If-Modified-Since
对应 Last-modified。服务器返回资源时,会携带 Last-modified,表示该资源最后修改的时间。客户端如果缓存数据,就需要把这个时间保存起来,在下一次请求的时候用 If-Modified-Since 带上,让服务器判断资源的最后修改时间是否一致。如果一致,就返回304,让客户端直接使用本地缓存。否则说明资源被修改,返回新资源和新的 Last-modified。
Last-modified
资源最后修改时间,配合 If-Modified-Since 使用。属于响应头字段。
ETag
资源的特定版本标识符,可以类比软件的版本号,需要配合 If-None-Match 使用。另外,这个 E 是 Entity(实体)的意思。
If-None-Match
效果类似 If-Modified-Since,客户端第一次请求资源时会拿到响应头里的 ETag 字段,将其保存起来。下次请求时,就作为 If-None-Match 头字段的值进行请求。ETag 通常使用的是弱比较算法,即如果两个资源语义一致,可看作为匹配成功。如果匹配成功,返回 304,否则返回新资源和新的 ETag。另外,ETag 通常会用 W/
开头,表示使用了弱匹配算法。ETag 可以用于跟踪用户,某种程度上,可以作为 cookie 的替代品。该头字段的优先度比 If-Modified-Since 高。
Cache-Control
通用消息头字段,在请求头和响应头中有不同的语义,用于实现缓存控制。
在响应头中,有很多值可以选择:
-
max-age=<seconds>
表示服务器提供的资源的有效期,单位为秒。需要注意的是,这个有效期是从响应报文生成的时刻开始计算的。这点和 cookie 是从客户端拿到响应报文的时刻开始计算不同 -
no-store
表示不允许客户端进行缓存。这个通常用于动态页面,比如微博首页。 -
no-cache
表示客户端每次使用本地缓存前,要要先去服务器验证。 -
must-revalidate
表示可以使用缓存,但过期后如果还想继续用,要先去服务器端进行验证。 -
private
表示客户端可以缓存,但代理服务器不可以缓存。比如个人主页,登录时接口返回有 Set-Cookie 字段 -
public
表示客户端和代理服务器都可以缓存。用于代理服务器可以发挥内容缓存的作用。 -
proxy-revalidate
作用类似must-revalidate
,但作用在代理服务器上。表示代理服务器的缓存过期后,需要请求源服务器进行验证,不涉及到客户端。 -
s-maxage=<seconds>
代理上缓存的有效期时长。这里的 s 指的是 share。 -
no-transform
表示不允许代理对资源进行修改。因为代理有时候会对资源进行一些优化,比如将常见格式的图片转换为存储空间更小的 webp 格式,返回给支持该格式的浏览器,以减少带宽。设置该值表示禁止这些操作。
而在客户端中,值有
-
max-age=0
表示客户端不再继续使用旧的本地缓存(有效期已经被我设为0了),希望服务器返回一个最新的资源。 -
no-cache
效果同max-age=0
。 -
max-stale=<seconds>
仅适用于代理,表示资源过期后在指定时间内依旧视为有效。 -
min-fresh=<seconds>
表示客户端希望获得的资源可以在一定时间内保持最新状态 -
only-if-cached
表示客户端只接受代理缓存的数据,如果代理没有缓存数据,不允许回源获取新资源返回给客户端。
Expire
资源无效的时间节点。优先级比 Cache-Control
低。格式例子: Expires: Thu, 05 Dec 2019 16:27:43 GMT
Vary
主要用于 代理服务器实现缓存服务,属于响应头字段。不同客户端对内容格式的支持程度不同(比如有些支持数据压缩,有些不支持),所以即便请求URL 和请求方法都相同,服务器返回的数据也会不同(称为内容协商)。Vary 字段记录了代理服务器返回特定数据参考了哪些请求字段。更具体的介绍可以看我的另一篇文章:响应报文中的 Vary 头字段的作用
Via
通用字段,记录经过的代理节点的信息。常用于代理服务器和源服务器上,假设客户端发送的请求依次经过了代理服务器A和代理服务器B,最终达到源服务器,则源服务器收到的字段为 Via: A, B
。该头字段的作用是追踪消息的转发情况,防止代理服务器之间形成环导致消息死循环。
X-Forwarded-For
Via 没有记录真正的发送者客户端的 IP,所以出现了这个没有纳入 HTTP 标准但已经是事实上的标准。该字段记录的是当前节点的请求方的 IP 地址,即记录的内容最终为 X-Forwarded-For: client, A, B
。另外,为了解决代理转发时,为了添加信息必须解析 HTTP 报文修改数据造成的成本,出现了 代理协议(The PROXY protocol),原理是将一些信息放到了HTTP报文的前面。具体原理本文不做详细介绍。
X-Real-IP
只记录客户端的 IP 地址。
网友评论