日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HTTP 协议中 Vary

發布時間:2023/12/9 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTTP 协议中 Vary 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自https://imququ.com/post/vary-header-in-http.html

HTTP 協議中 Vary 的一些研究

文章目錄

  • HTTP 內容協商
  • 有 BUG 的緩存服務
  • Nginx 和 SPDY

經常抓包看 HTTP 請求的同學應該對 Vary 這個響應頭字段并不陌生,它有什么用?用?PageSpeed工具檢查頁面時,經常看到「Specify a Vary: Accept-Encoding header(請指定一個 Vary: Accept-Encoding 標頭)」這樣的建議,為什么要這樣做?本文記錄我對 Vary 的一些研究,其中就包含這些問題的答案。

HTTP 內容協商

要了解 Vary 的作用,先得了解 HTTP 的內容協商機制。有時候,同一個 URL 可以提供多份不同的文檔,這就要求服務端和客戶端之間有一個選擇最合適版本的機制,這就是內容協商。

協商方式有兩種,一種是服務端把文檔可用版本列表發給客戶端讓用戶選,這可以使用 300 Multiple Choices 狀態碼來實現。這種方案有不少問題,首先多一次網絡往返;其次服務端同一文檔的某些版本可能是為擁有某些技術特征的客戶端準備的,而普通用戶不一定了解這些細節。舉個例子,服務端通常可以將靜態資源輸出為壓縮和未壓縮兩個版本,壓縮版顯然是為支持壓縮的客戶端而準備的,但如果讓普通用戶選,很可能選擇錯誤的版本。

所以 HTTP 的內容協商通常使用另外一種方案:服務端根據客戶端發送的請求頭中某些字段自動發送最合適的版本。可以用于這個機制的請求頭字段又分兩種:內容協商專用字段(Accept 字段)、其他字段。

首先來看 Accept 字段,詳見下表:

請求頭字段 說明 響應頭字段
Accept 告知服務器發送何種媒體類型 Content-Type
Accept-Language 告知服務器發送何種語言 Content-Language
Accept-Charset 告知服務器發送何種字符集 Content-Type
Accept-Encoding 告知服務器采用何種壓縮方式 Content-Encoding

例如客戶端發送以下請求頭:

BASHAccept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:zh-CN,en-US;q=0.8,en;q=0.6

表示它可以接受任何 MIME 類型的資源;支持采用 gzip、deflate 或 sdch 壓縮過的資源;可以接受 zh-CN、en-US 和 en 三種語言,并且 zh-CN 的權重最高(q 取值 0 - 1,最高為 1,最低為 0,默認為 1),服務端應該優先返回語言等于 zh-CN 的版本。

瀏覽器的響應頭可能是這樣的:

Content-Type: text/javascript Content-Encoding: gzip

表示這個文檔確切的 MIME 類型是 text/javascript;文檔內容進行了 gzip 壓縮;響應頭沒有 Content-Language 字段,通常說明返回版本的語言正好是請求頭 Accept-Language 中權重最高的那個。

有時候,上面四個 Accept 字段并不夠用,例如要針對特定瀏覽器如 IE6 輸出不一樣的內容,就需要用到請求頭中的 User-Agent 字段。類似的,請求頭中的 Cookie 也可能被服務端用做輸出差異化內容的依據。

由于客戶端和服務端之間可能存在一個或多個中間實體(如緩存服務器),而緩存服務最基本的要求是給用戶返回正確的文檔。如果服務端根據不同 User-Agent 返回不同內容,而緩存服務器把 IE6 用戶的響應緩存下來,并返回給使用其他瀏覽器的用戶,肯定會出問題 。

所以 HTTP 協議規定,如果服務端提供的內容取決于 User-Agent 這樣「常規 Accept 協商字段之外」的請求頭字段,那么響應頭中必須包含 Vary 字段,且 Vary 的內容必須包含 User-Agent。同理,如果服務端同時使用請求頭中 User-Agent 和 Cookie 這兩個字段來生成內容,那么響應中的 Vary 字段看上去應該是這樣的:

Vary: User-Agent, Cookie

也就是說 Vary 字段用于列出一個響應字段列表,告訴緩存服務器遇到同一個 URL 對應著不同版本文檔的情況時,如何緩存和篩選合適的版本。

有 BUG 的緩存服務

再來看 PageSpeed 的「Specify a Vary: Accept-Encoding header」這個提示,按照上面的說明,Accept-Encoding 屬于內容協商專用字段,服務端只需要在響應頭中增加 Content-Encoding 字段,用來指明內容壓縮格式;或者不輸出 Content-Encoding 表明內容未經過壓縮就可以了。而緩存服務器,應該針對不同的 Content-Encoding 緩存不同內容,再根據具體請求中的 Accept-Encoding 字段返回最合適的版本。

但是有些實現得有 BUG 的緩存服務器,會忽略響應頭中的 Content-Encoding,從而可能給不支持壓縮的客戶端返回緩存的壓縮版本。有兩個方案可以避免這種情況發生:

  • 將響應頭中的 Cache-Control 字段設為 private,告訴中間實體不要緩存它;
  • 增加 Vary: Accept-Encoding 響應頭,明確告知緩存服務器按照 Accept-Encoding 字段的內容,分別緩存不同的版本;
  • 通常為了更好的利用中間實體的緩存功能,我們都用第二種方案。

    對于 css、js 這樣的靜態資源,只要客戶端支持 gzip,服務端應該總是啟用它;同時為了避免有 BUG 的緩存服務器給用戶返回錯誤的版本,還應該輸出 Vary: Accept-Encoding。

    Nginx 和 SPDY

    通常,上面說的這些工作,Web Server 都可以幫我們搞定。對于 Nginx 來說,下面這個配置可以自動給啟用了 gzip 的響應加上 Vary: Accept-Encoding:

    gzip_vary on;

    用 curl 驗證我博客的 js 文件,響應頭如下:

    BASHjerry@www:~$ curl --head https://imququ.com/.../xx.jsHTTP/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: Accept-Encoding」,一切正常。

    但是用 Chrome 自帶抓包工具看下,這個響應頭卻是這樣:

    BASHHTTP/1.1 200 OK cache-control: max-age=315360000 content-encoding: gzip content-type: application/x-javascript date: Tue, 31 Dec 2013 16:35:27 GMT expires: Fri, 29 Dec 2023 16:35:27 GMT last-modified: Tue, 31 Dec 2013 14:30:52 GMT server: nginx status: 200 strict-transport-security: max-age=31536000 version: HTTP/1.1

    我的博客支持 SPDY/2 協議,用 Chrome 訪問我博客會走 SPDY,所以上面的響應頭看上有點不同尋常,例如字段名都變成了小寫;多了 status、version 等字段,這些變化下次專門介紹(注:見「SPDY 3.1 中的請求 / 響應頭」)。神奇的是盡管服務端沒任何變化,但響應中的 Vary: Accept-Encoding 卻不見了。

    SPDY 規定客戶端必須支持壓縮,這意味著 SPDY 服務器可以直接啟用壓縮而不用關心請求頭中的 Accept-Encoding 字段。下面這段來自 Nginx 支持的 SPDY/2 協議:

    User-agents are expected to support gzip and deflate compression. Regardless of the Accept-Encoding sent by the user-agent, the server may select gzip or deflate encoding at any time.?[via]

    于是,對于支持 SPDY 的客戶端來說,Vary: Accept-Encoding 沒有用途,Nginx 選擇直接去掉它,可以節省一點流量。curl 或其他不支持 SPDY 協議的客戶端還是走 HTTP 協議,所以看到的響應頭是常規的。

    Nginx 的這個做法是否合適一直有爭論,實際上并不是所有支持 SPDY 的 Web Server 都會這么做。例如即使通過 SPDY 協議訪問 Google 首頁的 js 文件,依然可以看到 vary: Accept-Encoding:

    BASHHTTP/1.1 200 OK status: 200 OK version: HTTP/1.1 age: 25762 alternate-protocol: 443:quic cache-control: public, max-age=31536000 content-encoding: gzip content-length: 154614 content-type: text/javascript; charset=UTF-8 date: Tue, 31 Dec 2013 23:23:51 GMT expires: Wed, 31 Dec 2014 23:23:51 GMT last-modified: Mon, 16 Dec 2013 21:54:35 GMT server: sffe vary: Accept-Encoding x-content-type-options: nosniff x-xss-protection: 1; mode=block

    另外,現階段 Chrome 和 Firefox 都支持 SPDY 協議,但 PageSpeed Chrome 版和 Firefox 版都沒有針對 SPDY 協議做特別處理,所以用它們測試我的博客,還是會提示「Specify a Vary: Accept-Encoding header」,這有點讓人哭笑不得。不過PageSpeed 在線版?已經更新規則,估計擴展版也快了。如果你有潔癖,可以在 Nginx 配置里加上「add_header vary accept-encoding;」手動輸出?Vary?響應頭。

    PS:Vary 在 IE 下有很多坑,使用時要格外小心。網上這部分文章比較多,例如 hax 早年寫的?IE 與 Vary 頭,可以點過去了解下。

    本文鏈接:https://imququ.com/post/vary-header-in-http.html,參與評論 ?

    --EOF--

    提醒:本文最后更新于?957?天前,文中所描述的信息可能已發生改變,請謹慎使用。

    專題「HTTP 相關」的其他文章??

    • 關于啟用 HTTPS 的一些經驗分享(三)?(May 05, 2016)
    • 如何壓縮 HTTP 請求正文?(Apr 18, 2016)
    • HTTP 協議中的 Content-Encoding?(Apr 17, 2016)
    • 三種解密 HTTPS 流量的方法介紹?(Mar 28, 2016)
    • HTTP Public Key Pinning 介紹?(Mar 05, 2016)
    • 關于啟用 HTTPS 的一些經驗分享(二)?(Dec 22, 2015)
    • 關于啟用 HTTPS 的一些經驗分享(一)?(Dec 04, 2015)
    • HTTP 代理原理及實現(二)?(Nov 20, 2015)
    • HTTP 代理原理及實現(一)?(Nov 20, 2015)
    • Content Security Policy Level 2 介紹?(Oct 05, 2015)

    總結

    以上是生活随笔為你收集整理的HTTP 协议中 Vary的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲免费在线观看av | 原神女裸体看个够无遮挡 | 里番acg★同人里番本子大全 | 免费看黄色片子 | 影音先锋久久 | 97精品 | 少妇熟女视频一区二区三区 | 国语对白真实视频播放 | 成人精品亚洲人成在线 | 丰满人妻一区二区三区在线 | 欧美精品乱码99久久蜜桃 | 级毛片 | 亚洲美女性视频 | 亚洲欧美日韩精品色xxx | 久久久久久久亚洲 | 久久精品一二三 | 欧美一区二区三 | 亚洲精品国产精华液 | 色爱av| 欧洲亚洲一区 | 国产精品偷伦视频免费观看了 | av一二三四区 | 探花系列在线观看 | 成人性做爰aaa片免费 | 三级网站免费观看 | 亚洲啪 | 黄色天堂网 | 亚洲一区二区蜜桃 | xvideos永久免费入口 | 高清视频在线播放 | 蜜臀99久久精品久久久久久软件 | 天堂网wwww| 男人懂得网站 | 国产成人99久久亚洲综合精品 | 久草中文网 | 性久久久久久久久 | www四虎影院| 久久视频黄色 | a级片一级片 | 亚洲成人网络 | 最新在线视频 | 亚洲网站免费看 | 天天操天天做 | 亚洲暴爽 | 天天插天天狠 | 欧美性xxxxxx | 色黄视频在线观看 | 99久久久无码国产精品 | 91香蕉国产在线观看 | 国产一级理论 | 亚洲三页 | 亚洲国产精品国自产拍久久 | 亚洲一区二区三区在线视频观看 | 337p日本欧洲亚洲鲁鲁 | 日本在线一区二区 | 视频一区二区三区在线观看 | 黄色网址www | 亚洲最大的av网站 | 国产精品aaa| 爆操欧美美女 | 国产三级久久久 | 人民的名义第二部 | 国产精品熟女一区二区不卡 | 成年人视频在线免费看 | 欧美自拍偷拍第一页 | 名人明星三级videos | 黄色网页在线免费观看 | 奇米色婷婷 | 在线成人| 欧美乱欲视频 | 黄网站色视频免费观看 | 欧美在线va| porn亚洲 | 美女精品久久久 | 一级特黄bbbbb免费观看 | 伊伊总综合网 | 青青草操 | 国产黑人| 精品人妻在线视频 | 日本一区二区在线观看视频 | 成人在线精品 | 久草热在线观看 | 日本一二三视频 | 日韩视频免费观看高清 | 国产精品网站在线观看 | 久草毛片 | 国产精品123 | 日韩三级久久 | 无码无遮挡又大又爽又黄的视频 | 九草av| www插插插无码免费视频网站 | 在线观看黄色片网站 | 精品亚洲aⅴ无码一区二区三区 | 樱花影院电视剧免费 | 国产成人欧美 | 成人免费性生活视频 | 成人免费一区 | 精品乱码一区二区三区 | 日韩欧美在线一区二区三区 |