http內容協商

概覽
對於特定的URL來講,服務器能夠根據一些原則來決定發送什麼內容給客戶端最合適。在有些場合下,服務器甚至能夠自動生成定製的頁面。好比,服務器能夠爲手持設備把HTML頁面轉換成WML頁面。這類動態內容變換被稱爲轉碼。這些變換動做是HTTP客戶端和服務器之間進行內容協商的結果
  共有3種不一樣的方法能夠決定服務器上哪一個頁面最適合客戶端:讓客戶端來選擇、服務器自動斷定,或讓中間代理來選。這3種技術分別稱爲客戶端驅動的協商、服務器驅動的協商以及透明協商
http內容協商
1 客戶端驅動
對於服務器來講,收到客戶端請求時只是發回響應,在其中列出可用的頁面,讓客戶端決定要看哪一個,這是最容易的事情。很顯然,這是服務器最容易實現的方式,並且客戶端極可能選擇到最佳的版本(只要列表中有讓客戶端選擇的足夠信息)。不利之處是每一個頁面都須要兩次請求:第一次獲取列表,第二次獲取選擇的副本。這種技術速度很慢且過程枯燥乏味,讓用戶厭煩
  從實現原理上來講,服務器實際上有兩種方法爲客戶端提供選項:一是發送回一個HTML文檔,裏面有到該頁面的各類版本的連接和每一個版本的描述信息,另外一種方法是發送回HTTP/1.1響應時,使用300 Multiple Choices響應代碼。客戶端瀏覽器收到這種響應時,在前一種狀況下,會顯示一個帶有連接的頁面,在後一種狀況下,可能會彈出對話窗口,讓用戶作選擇。無論怎麼樣,決定是由客戶端的瀏覽器用戶做出的
  除了增長時延而且對每一個頁面都要進行繁瑣的屢次請求以外,這種方法還有一個缺點:它須要多個URL:公共頁面要一個,其餘每種特殊頁面也都要一個。所以,好比說原始的請求地址是www.joes-hardware.com, Joe的服務器可能會回覆某個頁面,該頁面裏面有到www.joes-hardware.com/english和www.joes-hardware.com/french 的連接。若是客戶端想加書籤的話,是要加在原始的公共頁面上呢,仍是加在選中的頁面上呢?若是用戶想把這個網站推薦給他的朋友,是告知www.joes-hardware.com 這個地址好呢,仍是隻告訴他們講英語的朋友www.joes-hardware.com/english 這個地址?
2 服務器驅動
減小額外通訊量的一種方法是讓服務器來決定發送哪一個頁面回去,但爲了作到這一點,客戶端必須發送有關客戶偏好的足夠信息,以便服務器可以做出準確的決策。服務器經過客戶端請求的首部集來得到這方面的信息
有如下兩種機制可供HTTP服務器評估發送什麼響應給客戶端比較合適
一、檢査內容協商首部集。服務器察看客戶端發送的Accept首部集,設法用相應的響應首部與之匹配
二、根據其餘(非內容協商)首部進行變通。例如,服務器能夠根據客戶端發送的User-Agent首部來發送響應
2.1 內容協商首部集
客戶端能夠用下面列出的HTTP首部集發送用戶的偏好信息
首部           描述
Accept        告知服務器發送何種媒體類型
Accept-Language 告知服務器發送何種語言
Accept-Charset   告知服務器發送何種字符集
Accept-Encoding 告知服務器採用何種編碼
[注意]這些首部與實體首部很是相似。不過,這兩種首部的用途大相徑庭。實體首部集像運輸標籤,它們描述了把報文從服務器傳輸給客戶端的過程當中必須的各類報文主體屬性。而內容協商首部集是由客戶端發送給服務器用於交換偏好信息的,以便服務器能夠從文檔的不一樣版本中選擇出最符合客戶端偏好的那個來提供服務html

服務器用下面列出的實體首部集來匹配客戶端的Accept首部集
Accept首部    實體首部
Accept       Content-Type
Accept-Language Content-Language
Accept-Charset Content-Type
Accept-Encoding Content-Encoding
因爲HTTP是無狀態的協議,表示服務器不會在不一樣的請求之間追蹤客戶端的偏好,因此客戶端必須在每一個請求中都發送其偏好信息
若是兩個客戶端都發送了Accept-Language首部,描述它們感興趣的語言信息,服務器就可以決定發送www.joes-hardware.com的何種版本給哪一個客戶端了。讓服務器自動選擇發送回去的文檔,減小了往返通訊的時延,這種時延是客戶端驅動模型中沒法避免的
然而,假設某個客戶端偏好西班牙文,那服務器應當回送哪一個版本的頁面呢?英語仍是法語?服務器只有兩種選擇:猜想或回退到客戶端驅動模型,問客戶端選擇哪一個。假如這個西班牙人碰巧懂一點英語,他可能會選擇英文頁面,這不是最理想的,但它能解決問題。在這種狀況下,這個西班牙人須要有辦法傳達更多與其偏好有關的信息,也就是他的確對英語略知一二,在沒有西班牙語的時候,英語也行
幸運的是,HTTP提供了一種機制,可讓與這個西班牙人狀況相似的客戶端更詳細地描述其偏好。這種機制就是質量值(簡稱q值)
HTTP協議中定義了質量值,容許客戶端爲每種偏好類別列出多種選項,併爲每種偏好選項關聯一個優先次序。例如,客戶端能夠發送下列形式的Accept-Language首部:
Accept-Language: en; q=0.5, fr; q=0.0 , nl; q=1.0, tr; q=0.0
其中q值的範圍從0.0-1.0(0.0是優先級最低的,而1.0是優先級最高的)。上面列出的那個首部,說明該客戶端最願意接收荷蘭語(縮寫爲nl)文檔,但英語(縮寫爲en)文檔也行;不管如何,這個客戶端都不肯意收到法語(縮寫爲fr)或土耳 其語(縮寫爲tr)的版本
[注意]偏好的排列順序並不重要,只有與偏好相關的q值纔是重要的
服務器偶爾也會碰到找不到文檔能夠匹配客戶端的任何偏好的狀況。對於這種狀況,服務器能夠修改文檔,也就是對文檔進行轉碼,以匹配客戶端的偏好
2.2 常見的http內容協商首部
Accept-Language: zh-cn,zh;q=0.5
  意思:瀏覽器支持的語言分別是中文和簡體中文,優先支持簡體中文。
  詳解:
  Accept-Language表示瀏覽器所支持的語言類型;
  zh-cn表示簡體中文;zh 表示中文;
  q是權重係數,範圍 0 =< q <= 1,q 值越大,請求越傾向於得到其「;」以前的類型表示的內容,若沒有指定 q 值,則默認爲1,若被賦值爲0,則用於提醒服務器哪些是瀏覽器不接受的內容類型。
http內容協商
Accept-Encoding: gzip, deflate,br
  意思:瀏覽器支持的壓縮編碼是 gzip 和 deflate。
  詳解:
  Accept-Encoding表示瀏覽器有能力解碼的編碼類型;
  gzip是 GNU zip 的縮寫,它是一個 GNU 自由軟件的文件壓縮程序,也常常用來表示 gzip 這種文件格式。
  deflate是同時使用了 LZ77 算法與哈夫曼編碼(Huffman Coding)的一個無損數據壓縮算法。
br是Brotli,是開發一種全新的數據格式,能夠提供比Zopfli高20-26%的壓縮比。據谷歌研究,Brotli壓縮速度同zlib的Deflate實現大體相同,而在Canterbury語料庫上的壓縮密度比LZMA和bzip2略大。
http內容協商算法

響應首部
http內容協商編程

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
  意思:瀏覽器支持的 MIME 類型分別是 text/html、application/xhtml+xml、application/xml 和 /,優先順序是它們從左到右的排列順序。
  詳解:
  Accept表示瀏覽器支持的 MIME 類型;
  MIME的英文全稱是 Multipurpose Internet Mail Extensions(多功能 Internet 郵件擴充服務),它是一種多用途網際郵件擴充協議,在1992年最先應用於電子郵件系統,但後來也應用到瀏覽器。
  text/html,application/xhtml+xml,application/xml 都是 MIME 類型,也能夠稱爲媒體類型和內容類型,斜槓前面的是 type(類型),斜槓後面的是 subtype(子類型);type 指定大的範圍,subtype 是 type 中範圍更明確的類型,即大類中的小類。
  Text:用於標準化地表示的文本信息,文本消息能夠是多種字符集和或者多種格式的;
  text/html表示 html 文檔;
  Application:用於傳輸應用程序數據或者二進制數據;
  application/xhtml+xml表示 xhtml 文檔;
  application/xml表示 xml 文檔。
http內容協商瀏覽器

  Accept-Charset: GB2312,utf-8;q=0.7,;q=0.7
  意思:瀏覽器支持的字符編碼分別是 GB23十二、utf-8 和任意字符,優先順序是 GB23十二、utf-八、

  詳解:
  Accept-Charset告訴 Web 服務器,瀏覽器能夠接受哪些字符編碼;
  GB2312是中國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,又稱GB0,由中國國家標準總局發佈,1981年5月1日實施。GB2312 編碼通行於中國大陸;新加坡等地也採用此編碼。
  utf-8是 Unicode 的一種變長字符編碼又稱萬國碼,由 Ken Thompson 於1992年建立,如今已經標準化爲 RFC 3629。
  表示任意字符編碼,雖然 q 都是等於 0.7,但明確指定的 GB2312,utf-8 比 具備更高的優先級。
2.3 其餘首部集
服務器也能夠根據其餘客戶端請求首部集來匹配響應,好比User-Agent首部。例如,服務器知道老版本的瀏覽器不支持JavaScript語言,這樣就能夠向其發送不含有JavaScript的頁面版本
在這種狀況下,沒有q值機制可供査找「最近似」的匹配。服務器或者去找徹底匹配,或者簡單地有什麼就給什麼,這取決於服務器的實現
因爲緩存須要盡力提供所緩存文檔中正確的「最佳」版本,HTTP協議定義了服務器在響應中發送的Vary首部。這個首部告知緩存,還有客戶端和全部下游的代理,服務器根據哪些首部來決定發送響應的最佳版本緩存

3 透明協商
透明協商機制試圖從服務器上去除服務器驅動協商所需的負載,並用中間代理來表明客戶端以使與客戶端的報文交換最小化。假定代理了解客戶端的預期,這樣就能夠表明客戶端與服務器協商,在客戶端請求內容的時候,代理已經收到了客戶端的預期
爲了支持透明內容協商,服務器必須有能力告知代理,服務器須要檢査哪些請求首部,以便對客戶端的請求進行最佳匹配。HTTP/1.1規範中沒有定義任何透明協商機制,但定義了Vary首部。服務器在響應中發送了Vary首部,以告知中間節點須要使用哪些請求首部進行內容協商
代理緩存能夠爲經過單個URL訪問的文檔保存不一樣的副本。若是服務器把它們的決策過程傳給緩存,這些代理就能表明服務器與客戶端進行協商。緩存同時也是進行內容轉碼的好地方,由於部署在緩存裏的通用轉碼器能對任意服務器,而不只僅是一臺服務器傳來的內容進行轉碼
3.1 緩存與備用候選
對內容進行緩存的時候是假設內容之後還能夠重用。然而,爲了確保對客戶端請求回送的是正確的已緩存響應,緩存必須應用服務器在回送響應時所用到的大部分決策邏輯
上面描述了客戶端發送的Accept首部集,以及爲了給每條請求選擇最佳的響應,服務器使用的與這些首部集匹配的相應實體首部集。緩存也必須使用相同的首部集來決定回送哪一個已緩存的響應
下圖展現了涉及緩存的正確及錯誤的操做序列。緩存把第一個請求轉發給服務器,並存儲其響應。對於第二個請求,緩存根據URL査找到了匹配的文檔。可是,這份文檔是法語版的,而請求者想要的是西班牙語版的。若是緩存只是把文檔的法語版本發給請求者的話,它就犯了錯誤
http內容協商安全

所以,緩存也應該把第二條請求轉發給服務器,並保存該URL的響應與「備用候選」響應。緩存如今就保存了同一個URL的兩份不一樣的文檔,與服務器上同樣。這些不一樣的版本稱爲變體(variant)或備用候選(alternate)。內容協商可當作是爲客戶端請求選擇最合適變體的過程
3.2 Varry首部
這裏是瀏覽器和服務器發送的一些典型的請求及相應首部
http內容協商服務器

然而,若是服務器的決策不是依據Accept首部集,而是好比User-Agent首部的話,狀況會如何?這不像聽起來這麼極端。例如,服務器可能知道老版本的瀏覽器不支持JavaScript語言,所以可能會回送不包含JavaScript的頁面版本。若是服務器是根據其餘首部來決定發送哪一個頁面的話,緩存必須知道這些首部是什麼,這樣才能在選擇回送的頁面時作出一樣的邏輯判斷
  HTTP的Vary響應首部中列出了全部客戶端請求首部,服務器可用這些首部來選擇文檔或產生定製的內容(在常規的內容協商首部集以外的內容)。例如,若所提供的文檔取決於User-Agent首部,Vary首部就必須包含User-Agent
  當新的請求到達時,緩存會根據內容協商首部集來尋找最佳匹配。但在把文檔提供給客戶端以前,它必須檢査服務器有沒有在已緩存響應中發送Vary首部。若是有Vary首部,那麼新請求中那些首部的值必須與舊的已緩存請求裏相應的首部相同。由於服務器可能會根據客戶端請求的首部來改變響應,爲了實現透明協商,緩存必須爲每一個已緩存變體保存客戶端請求首部和相應的服務器響應首部,參見下圖
http內容協商app

若是某服務器的Vary首部看起來像下面這樣,大量不一樣的User-Agent和Cookie值將會產生很是多的變體:

Vary: User-Agent, Cookie
緩存必須爲每一個變體保存其相應的文檔版本。當緩存執行査找時,首先會對內容協商首部集進行內容匹配,而後比較請求的變體與緩存的變體。若是沒法匹配,緩存就從原始服務器獲取文檔
3.3 轉碼
咱們已經討論了一個機制,該機制可讓客戶端和服務器從某個URL的一系列文檔中挑選出最適合客戶端的文檔。實現這些機制的前提是,存在一些知足客戶端需求的文檔——無論是徹底知足仍是在必定程度上知足
然而,若是服務器沒有能知足客戶端需求的文檔會怎麼樣呢?服務器能夠給出一個錯誤響應。但理論上,服務器能夠把現存的文檔轉換成某種客戶端可用的文檔。這種選項稱爲轉碼
下面列出了一些假設的轉碼
轉換以前             轉換以後
HTML文檔           WML文檔
高分辨率圖像         低分辨率圖像
彩×××像           黑白圖像
有多個框架的複雜頁面     沒有不少框架或圖像的簡單文本頁面
有Java小應用程序的HTML頁面 沒有Java小應用程序的HTML頁面
有廣告的頁面         去除廣告的頁面框架

有3種類別的轉碼:格式轉換、信息綜合以及內容注入
3.3.1 格式轉換
格式轉換是指將數據從一種格式轉換成另外一種格式,使之能夠被客戶端査看。經過HTML到WML的轉換,無線設備就能夠訪問一般供桌面客戶端査看的文檔了。經過慢速鏈接訪問Web頁面的客戶端並不須要接收高分辨率圖像,若是經過格式轉換下降圖像分辨率和顏色來減少圖像文件大小的話,這類客戶端就能更容易地査看圖像比較豐富的頁面了
格式轉換能夠由內容協商首部集來驅動,但也能由User-Agent首部來驅動。注意,內容轉換或轉碼與內容編碼或傳輸編碼是不一樣的,後二者通常用於更高效或安全地傳輸內容,而前二者則可以使訪問設備可以査看內容
3.3.2 信息綜合
從文檔中提取關鍵的信息片斷稱爲信息綜合(information synthesis),這是一種有用的轉碼操做。這種操做的例子包括根據小節標題生成文檔的大綱,或者從頁面中刪除廣告和商標
根據內容中的關鍵字對頁面分類是更精細的技術,有助於總結文檔的精髓。這種技術經常使用於Web頁面分類系統中,好比門戶網站的Web頁面目錄
3.3.3 內容注入
前面描述的兩類轉碼一般會減小Web文檔的內容,但還有另外一類轉換會增長文檔的內容,即內容注入轉碼。內容注入轉碼的例子有自動廣告生成器和用戶追蹤系統
設想一下,一個能往途經的每一個HTML頁面中自動添加廣告的廣告植入轉碼器是多麼的誘人,固然也很煩人。這類轉碼操做只能動態進行——它必須即時添加與當前的特定用戶有關,或針對特定用戶的廣告。也能夠構建用戶追蹤系統,在頁面中動態增長內容,用於收集用戶査看頁面和客戶端瀏覽方式的統計信息
3.3.4 轉碼與靜態預生產的對比
轉碼的替代作法是在Web服務器上創建Web頁面的不一樣副本,例如一個是HTML,一個是WML;一個圖像分辨率高,一個圖像分辨率低;一個有多媒體內容,一個沒有。可是,這種方法不是很切合實際,緣由不少:某個頁面中的任何小改動都會牽扯不少頁面,須要不少空間來存儲各頁面的不一樣版本,並且使頁面編目和Web服務器編程(以提供正確的版本)變得更加困難。有些轉碼操做,好比廣告插入(尤爲是定向廣告插入),就不能靜態實現——由於插入什麼廣告和請求頁面的用戶有關
對單一的根頁面進行即時轉換,是比靜態的預生成更容易的解決方案。但這樣會在提供內容時增長時延。不過有時候其中一些計算能夠由第三方進行,這樣就減小了Web服務器上的計算負荷——好比能夠由代理或緩存中的外部Agent完成轉換
下圖顯示了在代理緩存中進行的轉碼
http內容協商ide

相關文章
相關標籤/搜索