2 篇文章 0 订阅

# 2.讲解

Vary一般出现在HTTP请求的响应信息头部，比如像下面这样：

HTTP/1.0 200 OK
Date: Fri, 24 Sep 2010 23:09:32 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: en-US
Vary: Accept-Encoding,User-Agent
Age: 1235
X-Cache: HIT from cache.kolich.local
X-Cache-Lookup: HIT from cache.kolich.local:80
Content-Length: 25090
Connection: close 

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 31 Dec 2013 16:34:48 GMT
Content-Type: application/x-javascript
Content-Length: 66748
Last-Modified: Tue, 31 Dec 2013 14:30:52 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "52c2d51c-104bc"
Expires: Fri, 29 Dec 2023 16:34:48 GMT
Cache-Control: max-age=315360000
Strict-Transport-Security: max-age=31536000
Accept-Ranges: bytes

Vary出现在响应信息中的作用是什么呢？首先这是由服务器端添加，添加到响应头部。大部分情况下是用在客户端缓存机制或者是缓存服务器在做缓存操作的时候，会使用到Vary头，会读取响应头中的Vary的内容，进行一些缓存的判断。接下来我们就来说一下Vary如何做缓存判断。

1. Accept-Encoding表示客户端支持的编码格式，常见的编码格式有gzip/compress/deflate/identity，服务器端会根据客户端提供的Accept-Encoding对返回的内容进行编码，并通过添加响应头Content-Encoding表明服务器端使用的编码格式。详解请参考我的另一篇博客[连接]；
2. User-Agent表示客户端代理，使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。这样服务器就能区别不同种类的客户端，做出不同的数据返回操作。

Vary: Accept-Encoding

Vary: Accept-Encoding,User-Agent

Vary: *

Vary存在于响应头中，它的内容来自于请求头中相关字段，Vary头的内容如果是多条则用“,”分割。缓存服务器会将某接口的首次请求结果缓存下来（包括响应头中的Vary），后面在发生相同请求的时候缓存服务器会拿着缓存的Vary来进行判断。比如Vary: Accept-Encoding,User-Agent，那么Accept-Encoding与User-Agent两个请求头的内容，就会作为判断是否返回缓存数据的依据，当缓存服务器中相同请求的缓存数据的编码格式、代理服务与当前请求的编码格式、代理服务一致，那就返回缓存数据，否则就会从服务器重新获取新的数据。当缓存服务器中已经缓存了该条请求，那么某次服务器端的响应头中如果Vary的值改变，则Vary会更新到该请求的缓存中去，下次请求会对比新的Vary内容。

Vary: * ，这个我不太理解，我个人的理解是，当Vary的值为“*”时，意味着请求头中的那些字段的值不能用来区分当前请求是从缓存服务拿还是重新请求获取，在Android的OkHttp框架中，客户端接收到服务器的响应数据，进行缓存处理时，一旦判断响应头有Vary:*时，就不缓存该条数据。所以我猜想缓存服务器会不会也是这样，当Vary的值为“*”时，不做缓存。

# 3.总结

1. Vary是作为响应头由服务器端返回数据时添加的头部信息；
2. Vary头的内容来自于当前请求的Request头部Key，比如Accept-Encoding、User-Agent等；
3. 缓存服务器进行某接口的网络请求结果数据缓存时，会将Vary一起缓存；
4. HTTP请求，缓存中Vary的内容会作为当前缓存数据是否可以作为请求结果返回给客户端的判断依据；
5. HTTP请求，响应数据中的Vary用来判断当前缓存中同请求的数据的Vary是否失效，如果缓存中的Vary与服务器刚拿到的Vary不一致，则可以进行更新。
6. 当Vary的值为“*”，意味着请求头中的所有信息都不可作为是否从缓存服务器拿数据的判断依据。

# 4.疑问

7.1.4. Vary

The "Vary" header field in a response describes what parts of a request message, aside from the method, Host header field, and request target, might influence the origin server's process for selecting and representing this response. The value consists of either a single asterisk ("*") or a list of header field names (case-insensitive).

Vary = "*" / 1#field-name

A Vary field value of "*" signals that anything about the request might play a role in selecting the response representation, possibly including elements outside the message syntax (e.g., the client's network address). A recipient will not be able to determine whether this response is appropriate for a later request without forwarding the request to the origin server. A proxy MUST NOT generate a Vary field with a "*" value.

A Vary field value consisting of a comma-separated list of names indicates that the named request header fields, known as the selecting header fields, might have a role in selecting the representation. The potential selecting header fields are not limited to those defined by this specification.

For example, a response that contains

Vary: accept-encoding, accept-language

indicates that the origin server might have used the request's Accept-Encoding and Accept-Language fields (or lack thereof) as determining factors while choosing the content for this response.

An origin server might send Vary with a list of fields for two purposes:

1. To inform cache recipients that they MUST NOT use this response to satisfy a later request unless the later request has the same values for the listed fields as the original request (Section 4.1 of [RFC7234]). In other words, Vary expands the cache key required to match a new request to the stored cache entry. Fielding & Reschke Standards Track [Page 70]

2. To inform user agent recipients that this response is subject to content negotiation (Section 5.3) and that a different representation might be sent in a subsequent request if additional parameters are provided in the listed header fields (proactive negotiation).

An origin server SHOULD send a Vary header field when its algorithm for selecting a representation varies based on aspects of the request message other than the method and request target, unless the variance cannot be crossed or the origin server has been deliberately configured to prevent cache transparency. For example, there is no need to send the Authorization field name in Vary because reuse across users is constrained by the field definition (Section 4.2 of [RFC7235]). Likewise, an origin server might use Cache-Control directives (Section 5.2 of [RFC7234]) to supplant Vary if it considers the variance less significant than the performance cost of Vary's impact on caching.

• 25
点赞
• 35
收藏
• 打赏
• 6
评论
01-04
10-30
03-16 1531
04-12 135
06-11 1628
05-25 2282
03-15 994
09-17 142
11-08 928
04-25 224
08-17
04-13 299
12-02 657
08-04 423
02-24 394

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

Lone_Star斌

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。