响应报文中的 Vary 头字段的作用

简介: 前端西瓜哥

Vary 字段主要用于 代理服务器实现缓存服务

不同客户端对内容格式的支持程度不同(比如有些支持数据压缩,有些不支持),所以即便请求URL 和请求方法都相同,服务器返回的数据也会不同(称为内容协商)。

Vary 字段记录了代理服务器返回特定数据参考了哪些请求字段。

代理服务器拿到源服务器的响应报文,会根据 Vary 里的字段列表,缓存不同版本的数据。当客户端再次访问时,代理服务器会分析请求字段,返回正确的版本。

在叙述 Vary 的工作原理前,我们先简单了解一下什么是代理服务器。

代理服务器

客户端访问网站会发起请求,请求会被发送到所请求资源所在的服务器,服务器会将对应的资源返回给客户端。如果并发访问量很小,服务器并没有什么压力。

但如果并发量很大,我们就得考虑缓存了。缓存分为客户端缓存和服务器缓存。服务器缓存的方案,可以将数据直接缓存缓存到内存中,也可以将数据缓存到代理服务器中。

我们在客户端到服务器中间添加一些 代理服务器,它们的其中一个功能是 内容缓存。另外,为了进行区分,我们将真正提供数据的服务器称为 源服务器

配合 DNS,我们可以将访问分配到离客户端最近的代理服务器,从里面获取数据。如果没有数据,该代理服务器会再发送和客户端相同的请求给源服务器,并将从源服务器返回的数据缓存起来,并返回数据给客户端。

这样,下次客户端再次请求相同的资源时,代理服务器就可以直接返回数据而不需要再转发给源服务器。

代理服务器除了可以提供 内存缓存,还有以下几个作用:

  1. 健康检查
  2. 安全防护
  3. 加密卸载
  4. 数据过滤

下面我们就通过一个例子,来说明 Vary 在服务端缓存中发挥的作用。

举例说明 Vary 的工作原理

假设客户端 A 请求了一个数据,且该客户端支持 gzip 压缩,于是请求头字段中带有 Accept-Encoding: gzip

请求来到了代理服务器,但是里面没有缓存,所以代理服务器把请求又发送给了源服务器。源服务器拿到了请求报文,分析了一波,决定返回一个进行了 gzip 压缩的数据。

另外,源服务器还希望介于它和客户端之间的代理服务器,也能够像它一样优秀,可以根据 Accept-Encoding 返回正确的数据,于是在响应头字段中加上了 Vary: Accept-Encoding,并返回了数据A 给代理服务器。

数据A 来到了代理服务器,代理服务器取出了 Vary 字段,发现里面有个 Accept-Encoding,于是它明白了,它需要将当前响应报文的 Accept-Encoding 作为一个标志,映射到当前这个缓存数据A。即:

URL + 请求方法 + "Accept-Encoding: gzip" -> 数据A

代理服务器缓存好了源服务器的数据后,并保存了映射关系,就把数据返回给了客户端 A。

很快,客户端 A 又发送相同请求,代理服务器接收了请求且缓存还没过期,且发现请求头依旧有 Accept-Encoding: gzip,于是缓存命中了数据A,数据A被返回给了客户端A。

在缓存未过期的期间,只要任何一个客户端的请求头里有 Accept-Encoding: gzip且请求url,代理服务器返回的数据都是数据A。

不久后,不支持解压功能的客户端B 发送一个没有 Accept-Encoding 字段的请求。代理服务器拿到了数据,缓存没有命中,于是和上面一样,拿到一个新的缓存数据B,得到了一个新的映射关系:

URL + 请求方法 + 无 Accept-Encoding 的头字段 -> 数据B

如果代理服务器不使用 Vary,纯粹只是根据 请求URL和请求方法 来判断是否缓存命中,那不支持解压功能的 客户端B 就可能会错误拿到代理服务器中的被压缩过的 数据A。

通过 Vary 头字段,我们可以避免客户端B拿到一个无法解压的数据A。

总结

这便是 Vary 头字段的作用:增加代理服务器的是否缓存命中的变量,而不是仅根据 请求URL 和 请求方法 来决定是否命中。

相关文章
|
Java 数据库 Maven
根据请求中接收到的主动协商头字段,目标资源没有用户代理可以接受的当前表示
今天使用ssm框架搭建了一个项目,测试一个插入的接口结果返回406,但是数据库插入成功了,报错406是因为返回的结果接口无法解析。
876 0
|
5月前
|
存储 缓存
解析HTTP通用首部字段
【7月更文挑战第18天】HTTP通用首部字段是指,请求报文和响应报文双方都会使用的首部。
|
6月前
|
缓存
HTTP响应首部字段释义
【6月更文挑战第23天】响应首部字段是由服务器端向客户端返回响应报文中所使用的字段。
|
7月前
|
存储 缓存
HTTP通用首部字段
【4月更文挑战第28天】
HTTP通用首部字段
|
Web App开发 JSON 缓存
HTTP的请求方法,空行,body,介绍请求报头的内部以及粘包问题
HTTP的请求方法,空行,body,介绍请求报头的内部以及粘包问题
IP数据包的首部字段“首部长度”的值为1110,则该IP数据报首部的长度为多少字节?
IP数据包的首部字段“首部长度”的值为1110,则该IP数据报首部的长度为多少字节?
232 0
|
网络协议
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
ACK的累加规则-wireshark抓包分析-不包含tcp头部、ip头部、数据链路层头部等。
|
缓存 算法
HTTP协议中的ETag头字段如何实现快速判断资源是否变化?
HTTP协议中的ETag头字段如何实现快速判断资源是否变化?
200 0
|
网络协议
HTTP协议中的“X-Real-IP”头字段的作用是什么?底层原理是什么?
HTTP协议中的“X-Real-IP”头字段的作用是什么?底层原理是什么?
8559 0
|
缓存
HTTP首部的那些事,通用首部,请求首部
1.HTTP报文首部 HTTP请求报文: 在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成 HTTP响应报文: 在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。
111 0
HTTP首部的那些事,通用首部,请求首部