HTTP请求的响应头部Vary的理解
1.引言
由于我主要是做Android開發的,所以Vary很陌生,今天看到OkHttp源碼中,有對Vary的判斷,就在網上查詢并且仔細研究了一下,感覺比較有用,就記錄一下。
2.講解
簡單說一下我對Vary一些理解,自己的一點總結。
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如何做緩存判斷。
對于服務器提供的某個接口來說,有時候會出現不同種類的客戶端對其進行網絡請求獲取數據,不同的客戶端可能支持的壓縮編碼方式不同,可能有的客戶端不支持壓縮,那么服務器端返回的數據就不能壓縮,有的支持gzip編碼,那么服務器端就可以進行gzip編碼返回給客戶端,客戶端獲取到數據之后,做響應的gzip解碼。還有種情況,對于不同的客戶端,需要的內容不一樣,比如針對特定,瀏覽器要求輸出的內容不一樣,比如在IE6瀏覽器上要輸出不一樣的內容,這就需要服務器端做不同的數據返回。所以說,服務器提供的同一個接口,客戶端進行同樣的網絡請求,對于不同種類的客戶端可能需要的數據不同,服務器端的返回方式返回數據也會不同。對于這個問題的解決,我想很多人是清除的,我們可以在請求信息添加Accept-Encoding、User-Agent等頭部。
這些都沒有問題,順利的解決了我們上面提出的問題,然而,當使用到緩存的時候,就會有問題,比如要求針對IE5和IE6顯示不同的數據,針對同一接口的同樣的請求,緩存服務器中分別存儲了IE5和IE6兩份數據,由于同樣的接口同樣的請求,一旦服務器判定要從緩存中獲取數據的話,很有可能會導致兩個客戶端的請求拿到同一份數據,這就會讓那個數據展示出現問題;再比如說A類客戶端支持壓縮格式gzip,B類客戶端不支持壓縮,對于同一個接口同樣的請求,如果服務器端打算從緩存服務器中取出數據返回的話,A、B兩類客戶端可能會收到同樣的數據,這樣要就會導致編解碼出錯。
這時候我們的Vary響應頭就登場了,Vary的字面意思是“不一、多樣化”,顧名思義,它的存在區分同樣的網絡請求的不同之處,其實就是通過頭部信息來區分。一個簡單的Vary頭包括:
Vary: Accept-Encoding
Vary: Accept-Encoding,User-Agent
Vary: X-Some-Custom-Header,Host
Vary: *
Vary存在于響應頭中,它的內容來自于請求頭中相關字段,Vary頭的內容如果是多條則用“,”分割。緩存服務器會將某接口的首次請求結果緩存下來(包括響應頭中的Vary),后面在發生相同請求的時候緩存服務器會拿著緩存的Vary來進行判斷。比如Vary: Accept-Encoding,User-Agent,那么Accept-Encoding與User-Agent兩個請求頭的內容,就會作為判斷是否返回緩存數據的依據,當緩存服務器中相同請求的緩存數據的編碼格式、代理服務與當前請求的編碼格式、代理服務一致,那就返回緩存數據,否則就會從服務器重新獲取新的數據。當緩存服務器中已經緩存了該條請求,那么某次服務器端的響應頭中如果Vary的值改變,則Vary會更新到該請求的緩存中去,下次請求會對比新的Vary內容。
官方解釋Vary頭:告知下游的代理服務器,應當如何對以后的請求協議頭進行匹配,以決定是否可使用已緩存的響應內容而不是重新從原服務器請求新的內容。
Vary: * ,這個我不太理解,我個人的理解是,當Vary的值為“*”時,意味著請求頭中的那些字段的值不能用來區分當前請求是從緩存服務拿還是重新請求獲取,在Android的OkHttp框架中,客戶端接收到服務器的響應數據,進行緩存處理時,一旦判斷響應頭有Vary:*時,就不緩存該條數據。所以我猜想緩存服務器會不會也是這樣,當Vary的值為“*”時,不做緩存。
3.總結
4.疑問
當Vary的值為“*”時,意味著什么?Vary是否有更好的解釋?官網的英文本人實在是能力有限翻譯不過來,哪位大神有興趣,可以指點一二,我不勝感激,我把官網的英文解釋貼上來:
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.
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的HTTP请求的响应头部Vary的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个程序员的书法学习之路-法帖篇
- 下一篇: Java版本的Bot Framework