您好,登錄后才能下訂單哦!
一個(gè)URL常常需要代表若干不同的資源。例如那種需要以多種語言提供其內(nèi)容的網(wǎng)站站點(diǎn)。如果某個(gè)站點(diǎn)有說法語的和說英語的兩種用戶,它可能想用這兩種語言提供網(wǎng)站站點(diǎn)信息。理想情況下,服務(wù)器應(yīng)當(dāng)向英語用戶發(fā)送英文版,向法語用戶發(fā)送法文版——用戶只要訪問網(wǎng)站主頁(yè)就可以得到相應(yīng)語言的內(nèi)容
HTTP提供了內(nèi)容協(xié)商方法,允許客戶端和服務(wù)器作這樣的決定。通過這些方法,單一的URL就可以代表不同的資源(比如,同一個(gè)網(wǎng)站頁(yè)面的法語版和英語版),這些不同的版本稱為變體。本文將詳細(xì)介紹內(nèi)容協(xié)商
對(duì)于特定的URL來說,服務(wù)器可以根據(jù)一些原則來決定發(fā)送什么內(nèi)容給客戶端最合適。在有些場(chǎng)合下,服務(wù)器甚至可以自動(dòng)生成定制的頁(yè)面。比如,服務(wù)器可以為手持設(shè)備把HTML頁(yè)面轉(zhuǎn)換成WML頁(yè)面。這類動(dòng)態(tài)內(nèi)容變換被稱為轉(zhuǎn)碼。這些變換動(dòng)作是HTTP客戶端和服務(wù)器之間進(jìn)行內(nèi)容協(xié)商的結(jié)果
共有3種不同的方法可以決定服務(wù)器上哪個(gè)頁(yè)面最適合客戶端:讓客戶端來選擇、服務(wù)器自動(dòng)判定,或讓中間代理來選。這3種技術(shù)分別稱為客戶端驅(qū)動(dòng)的協(xié)商、服務(wù)器驅(qū)動(dòng)的協(xié)商以及透明協(xié)商
對(duì)于服務(wù)器來說,收到客戶端請(qǐng)求時(shí)只是發(fā)回響應(yīng),在其中列出可用的頁(yè)面,讓客戶端決定要看哪個(gè),這是最容易的事情。很顯然,這是服務(wù)器最容易實(shí)現(xiàn)的方式,而且客戶端很可能選擇到最佳的版本(只要列表中有讓客戶端選擇的足夠信息)。不利之處是每個(gè)頁(yè)面都需要兩次請(qǐng)求:第一次獲取列表,第二次獲取選擇的副本。這種技術(shù)速度很慢且過程枯燥乏味,讓用戶厭煩
從實(shí)現(xiàn)原理上來說,服務(wù)器實(shí)際上有兩種方法為客戶端提供選項(xiàng):一是發(fā)送回一個(gè)HTML文檔,里面有到該頁(yè)面的各種版本的鏈接和每個(gè)版本的描述信息,另一種方法是發(fā)送回HTTP/1.1響應(yīng)時(shí),使用300 Multiple Choices響應(yīng)代碼??蛻舳藶g覽器收到這種響應(yīng)時(shí),在前一種情況下,會(huì)顯示一個(gè)帶有鏈接的頁(yè)面,在后一種情況下,可能會(huì)彈出對(duì)話窗口,讓用戶做選擇。不管怎么樣,決定是由客戶端的瀏覽器用戶作出的
除了增加時(shí)延并且對(duì)每個(gè)頁(yè)面都要進(jìn)行繁瑣的多次請(qǐng)求之外,這種方法還有一個(gè)缺點(diǎn):它需要多個(gè)URL:公共頁(yè)面要一個(gè),其他每種特殊頁(yè)面也都要一個(gè)。因此,比如說原始的請(qǐng)求地址是www.joes-hardware.com,Joe的服務(wù)器可能會(huì)回復(fù)某個(gè)頁(yè)面,該頁(yè)面里面有到www.joes-hardware.com/english和www.joes-hardware.com/french的鏈接。如果客戶端想加書簽的話,是要加在原始的公共頁(yè)面上呢,還是加在選中的頁(yè)面上呢?如果用戶想把這個(gè)網(wǎng)站推薦給他的朋友,是告知www.joes-hardware.com這個(gè)地址好呢,還是只告訴他們講英語的朋友www.joes-hardware.com/english這個(gè)地址?
減少額外通信量的一種方法是讓服務(wù)器來決定發(fā)送哪個(gè)頁(yè)面回去,但為了做到這一點(diǎn),客戶端必須發(fā)送有關(guān)客戶偏好的足夠信息,以便服務(wù)器能夠作出準(zhǔn)確的決策。服務(wù)器通過客戶端請(qǐng)求的首部集來獲得這方面的信息
有以下兩種機(jī)制可供HTTP服務(wù)器評(píng)估發(fā)送什么響應(yīng)給客戶端比較合適
1、檢査內(nèi)容協(xié)商首部集。服務(wù)器察看客戶端發(fā)送的Accept首部集,設(shè)法用相應(yīng)的響應(yīng)首部與之匹配
2、根據(jù)其他(非內(nèi)容協(xié)商)首部進(jìn)行變通。例如,服務(wù)器可以根據(jù)客戶端發(fā)送的User-Agent首部來發(fā)送響應(yīng)
【內(nèi)容協(xié)商首部集】
客戶端可以用下面列出的HTTP首部集發(fā)送用戶的偏好信息
首部 描述 Accept 告知服務(wù)器發(fā)送何種媒體類型 Accept-Language 告知服務(wù)器發(fā)送何種語言 Accept-Charset 告知服務(wù)器發(fā)送何種字符集 Accept-Encoding 告知服務(wù)器采用何種編碼
[注意]這些首部與實(shí)體首部非常類似。不過,這兩種首部的用途截然不同。實(shí)體首部集像運(yùn)輸標(biāo)簽,它們描述了把報(bào)文從服務(wù)器傳輸給客戶端的過程中必須的各種報(bào)文主體屬性。而內(nèi)容協(xié)商首部集是由客戶端發(fā)送給服務(wù)器用于交換偏好信息的,以便服務(wù)器可以從文檔的不同版本中選擇出最符合客戶端偏好的那個(gè)來提供服務(wù)
服務(wù)器用下面列出的實(shí)體首部集來匹配客戶端的Accept首部集
Accept首部 實(shí)體首部 Accept Content-Type Accept-Language Content-Language Accept-Charset Content-Type Accept-Encoding Content-Encoding
由于HTTP是無狀態(tài)的協(xié)議,表示服務(wù)器不會(huì)在不同的請(qǐng)求之間追蹤客戶端的偏好,所以客戶端必須在每個(gè)請(qǐng)求中都發(fā)送其偏好信息
如果兩個(gè)客戶端都發(fā)送了Accept-Language首部,描述它們感興趣的語言信息,服務(wù)器就能夠決定發(fā)送www.joes-hardware.com的何種版本給哪個(gè)客戶端了。讓服務(wù)器自動(dòng)選擇發(fā)送回去的文檔,減少了往返通信的時(shí)延,這種時(shí)延是客戶端驅(qū)動(dòng)模型中無法避免的
然而,假設(shè)某個(gè)客戶端偏好西班牙文,那服務(wù)器應(yīng)當(dāng)回送哪個(gè)版本的頁(yè)面呢?英語還是法語?服務(wù)器只有兩種選擇:猜測(cè)或回退到客戶端驅(qū)動(dòng)模型,問客戶端選擇哪個(gè)。假如這個(gè)西班牙人碰巧懂一點(diǎn)英語,他可能會(huì)選擇英文頁(yè)面,這不是最理想的,但它能解決問題。在這種情況下,這個(gè)西班牙人需要有辦法傳達(dá)更多與其偏好有關(guān)的信息,也就是他的確對(duì)英語略知一二,在沒有西班牙語的時(shí)候,英語也行
幸運(yùn)的是,HTTP提供了一種機(jī)制,可以讓與這個(gè)西班牙人情況類似的客戶端更詳細(xì)地描述其偏好。這種機(jī)制就是質(zhì)量值(簡(jiǎn)稱q值)
HTTP協(xié)議中定義了質(zhì)量值,允許客戶端為每種偏好類別列出多種選項(xiàng),并為每種偏好選項(xiàng)關(guān)聯(lián)一個(gè)優(yōu)先次序。例如,客戶端可以發(fā)送下列形式的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是優(yōu)先級(jí)最低的,而1.0是優(yōu)先級(jí)最高的)。上面列出的那個(gè)首部,說明該客戶端最愿意接收荷蘭語(縮寫為nl)文檔,但英語(縮寫為en)文檔也行;無論如何,這個(gè)客戶端都不愿意收到法語(縮寫為fr)或土耳 其語(縮寫為tr)的版本
[注意]偏好的排列順序并不重要,只有與偏好相關(guān)的q值才是重要的
服務(wù)器偶爾也會(huì)碰到找不到文檔可以匹配客戶端的任何偏好的情況。對(duì)于這種情況,服務(wù)器可以修改文檔,也就是對(duì)文檔進(jìn)行轉(zhuǎn)碼,以匹配客戶端的偏好
【其他首部集】
服務(wù)器也可以根據(jù)其他客戶端請(qǐng)求首部集來匹配響應(yīng),比如User-Agent首部。例如,服務(wù)器知道老版本的瀏覽器不支持JavaScript語言,這樣就可以向其發(fā)送不含有JavaScript的頁(yè)面版本
在這種情況下,沒有q值機(jī)制可供査找“最近似”的匹配。服務(wù)器或者去找完全匹配,或者簡(jiǎn)單地有什么就給什么,這取決于服務(wù)器的實(shí)現(xiàn)
由于緩存需要盡力提供所緩存文檔中正確的“最佳”版本,HTTP協(xié)議定義了服務(wù)器在響應(yīng)中發(fā)送的Vary首部。這個(gè)首部告知緩存,還有客戶端和所有下游的代理,服務(wù)器根據(jù)哪些首部來決定發(fā)送響應(yīng)的最佳版本
【Apache】
下面概括了著名的Web服務(wù)器Apache是如何支持內(nèi)容協(xié)商的。網(wǎng)站的內(nèi)容提供者,比如說Joe要負(fù)責(zé)為Joe的索引頁(yè)面提供不同的版本。Joe還必須把這些索引頁(yè)面文件放在和站點(diǎn)相關(guān)的Apache服務(wù)器的適當(dāng)目錄下。用以下兩種方式可以啟用內(nèi)容協(xié)商
1、在網(wǎng)站目錄中,為網(wǎng)站中每個(gè)有變體的URI創(chuàng)建一個(gè)type-map(類型映射)文件。這個(gè)type-map文件列出了每個(gè)變體和其相關(guān)的內(nèi)容協(xié)商首部集
2、啟用MultiViews指令,這樣會(huì)使Apache自動(dòng)為目錄創(chuàng)建type-map文件
【使用type-map文件】
Apache服務(wù)器需要知道type-map文件的命名規(guī)則。可以在服務(wù)器的配置文件中設(shè)置handler來說明type-map文件的后綴名。例如:
AddHandler type-map .var
這行就說明了后綴是.var的文件就是type-map文件
下面給出一個(gè)type-map文件示例
根據(jù)這個(gè)type-map文件,Apache服務(wù)器就知道要發(fā)送joes-hardware.en.html給請(qǐng)求英語版的客戶端,發(fā)送joes-hardware.fr.de.html給請(qǐng)求法語版的客戶端。Apache服務(wù)器也支持質(zhì)量值
【使用MultiView】
為了使用MultiView,必須在網(wǎng)站目錄下的access.conf文件中的適當(dāng)小節(jié)(<Directory>、<Location>,或<Files>)使用OPTION指令來啟用它
如果啟用了MultiView,而瀏覽器又請(qǐng)求了名為joes-hardware的資源,服務(wù)器就會(huì)査找所有名字中含有joes-hardware的文件,并為它們創(chuàng)建type-map文件。服務(wù)器會(huì)根據(jù)名字猜測(cè)其對(duì)應(yīng)的內(nèi)容協(xié)商首部集。例如,法語版的joes-hardware應(yīng)當(dāng)含有.fr
另一種在服務(wù)器端實(shí)現(xiàn)內(nèi)容協(xié)商的方法是使用服務(wù)器端擴(kuò)展,比如微軟的動(dòng)態(tài)服務(wù)器頁(yè)面(Microsoft’s Active Server Pages, ASP)
透明協(xié)商機(jī)制試圖從服務(wù)器上去除服務(wù)器驅(qū)動(dòng)協(xié)商所需的負(fù)載,并用中間代理來代表客戶端以使與客戶端的報(bào)文交換最小化。假定代理了解客戶端的預(yù)期,這樣就可以代表客戶端與服務(wù)器協(xié)商,在客戶端請(qǐng)求內(nèi)容的時(shí)候,代理已經(jīng)收到了客戶端的預(yù)期
為了支持透明內(nèi)容協(xié)商,服務(wù)器必須有能力告知代理,服務(wù)器需要檢査哪些請(qǐng)求首部,以便對(duì)客戶端的請(qǐng)求進(jìn)行最佳匹配。HTTP/1.1規(guī)范中沒有定義任何透明協(xié)商機(jī)制,但定義了Vary首部。服務(wù)器在響應(yīng)中發(fā)送了Vary首部,以告知中間節(jié)點(diǎn)需要使用哪些請(qǐng)求首部進(jìn)行內(nèi)容協(xié)商
代理緩存可以為通過單個(gè)URL訪問的文檔保存不同的副本。如果服務(wù)器把它們的決策過程傳給緩存,這些代理就能代表服務(wù)器與客戶端進(jìn)行協(xié)商。緩存同時(shí)也是進(jìn)行內(nèi)容轉(zhuǎn)碼的好地方,因?yàn)椴渴鹪诰彺胬锏耐ㄓ棉D(zhuǎn)碼器能對(duì)任意服務(wù)器,而不僅僅是一臺(tái)服務(wù)器傳來的內(nèi)容進(jìn)行轉(zhuǎn)碼
【緩存與備用候選】
對(duì)內(nèi)容進(jìn)行緩存的時(shí)候是假設(shè)內(nèi)容以后還可以重用。然而,為了確保對(duì)客戶端請(qǐng)求回送的是正確的已緩存響應(yīng),緩存必須應(yīng)用服務(wù)器在回送響應(yīng)時(shí)所用到的大部分決策邏輯
上面描述了客戶端發(fā)送的Accept首部集,以及為了給每條請(qǐng)求選擇最佳的響應(yīng),服務(wù)器使用的與這些首部集匹配的相應(yīng)實(shí)體首部集。緩存也必須使用相同的首部集來決定回送哪個(gè)已緩存的響應(yīng)
下圖展示了涉及緩存的正確及錯(cuò)誤的操作序列。緩存把第一個(gè)請(qǐng)求轉(zhuǎn)發(fā)給服務(wù)器,并存儲(chǔ)其響應(yīng)。對(duì)于第二個(gè)請(qǐng)求,緩存根據(jù)URL査找到了匹配的文檔。但是,這份文檔是法語版的,而請(qǐng)求者想要的是西班牙語版的。如果緩存只是把文檔的法語版本發(fā)給請(qǐng)求者的話,它就犯了錯(cuò)誤
因此,緩存也應(yīng)該把第二條請(qǐng)求轉(zhuǎn)發(fā)給服務(wù)器,并保存該URL的響應(yīng)與“備用候選”響應(yīng)。緩存現(xiàn)在就保存了同一個(gè)URL的兩份不同的文檔,與服務(wù)器上一樣。這些不同的版本稱為變體(variant)或備用候選(alternate)。內(nèi)容協(xié)商可看成是為客戶端請(qǐng)求選擇最合適變體的過程
【Vary 首部】
這里是瀏覽器和服務(wù)器發(fā)送的一些典型的請(qǐng)求及響應(yīng)首部
然而,如果服務(wù)器的決策不是依據(jù)Accept首部集,而是比如User-Agent首部的話,情況會(huì)如何?這不像聽起來這么極端。例如,服務(wù)器可能知道老版本的瀏覽器不支持JavaScript語言,因此可能會(huì)回送不包含JavaScript的頁(yè)面版本。如果服務(wù)器是根據(jù)其他首部來決定發(fā)送哪個(gè)頁(yè)面的話,緩存必須知道這些首部是什么,這樣才能在選擇回送的頁(yè)面時(shí)做出同樣的邏輯判斷
HTTP的Vary響應(yīng)首部中列出了所有客戶端請(qǐng)求首部,服務(wù)器可用這些首部來選擇文檔或產(chǎn)生定制的內(nèi)容(在常規(guī)的內(nèi)容協(xié)商首部集之外的內(nèi)容)。例如,若所提供的文檔取決于User-Agent首部,Vary首部就必須包含User-Agent
當(dāng)新的請(qǐng)求到達(dá)時(shí),緩存會(huì)根據(jù)內(nèi)容協(xié)商首部集來尋找最佳匹配。但在把文檔提供給客戶端之前,它必須檢査服務(wù)器有沒有在已緩存響應(yīng)中發(fā)送Vary首部。如果有Vary首部,那么新請(qǐng)求中那些首部的值必須與舊的已緩存請(qǐng)求里相應(yīng)的首部相同。因?yàn)榉?wù)器可能會(huì)根據(jù)客戶端請(qǐng)求的首部來改變響應(yīng),為了實(shí)現(xiàn)透明協(xié)商,緩存必須為每個(gè)已緩存變體保存客戶端請(qǐng)求首部和相應(yīng)的服務(wù)器響應(yīng)首部,參見下圖
如果某服務(wù)器的Vary首部看起來像下面這樣,大量不同的User-Agent和Cookie值將會(huì)產(chǎn)生非常多的變體:
Vary: User-Agent, Cookie
緩存必須為每個(gè)變體保存其相應(yīng)的文檔版本。當(dāng)緩存執(zhí)行査找時(shí),首先會(huì)對(duì)內(nèi)容協(xié)商首部集進(jìn)行內(nèi)容匹配,然后比較請(qǐng)求的變體與緩存的變體。如果無法匹配,緩存就從原始服務(wù)器獲取文檔
我們已經(jīng)討論了一個(gè)機(jī)制,該機(jī)制可以讓客戶端和服務(wù)器從某個(gè)URL的一系列文檔中挑選出最適合客戶端的文檔。實(shí)現(xiàn)這些機(jī)制的前提是,存在一些滿足客戶端需求的文檔——不管是完全滿足還是在一定程度上滿足
然而,如果服務(wù)器沒有能滿足客戶端需求的文檔會(huì)怎么樣呢?服務(wù)器可以給出一個(gè)錯(cuò)誤響應(yīng)。但理論上,服務(wù)器可以把現(xiàn)存的文檔轉(zhuǎn)換成某種客戶端可用的文檔。這種選項(xiàng)稱為轉(zhuǎn)碼
下面列出了一些假設(shè)的轉(zhuǎn)碼
轉(zhuǎn)換之前 轉(zhuǎn)換之后 HTML文檔 WML文檔 高分辨率圖像 低分辨率圖像 彩×××像 黑白圖像 有多個(gè)框架的復(fù)雜頁(yè)面 沒有很多框架或圖像的簡(jiǎn)單文本頁(yè)面 有Java小應(yīng)用程序的HTML頁(yè)面 沒有Java小應(yīng)用程序的HTML頁(yè)面 有廣告的頁(yè)面 去除廣告的頁(yè)面
有3種類別的轉(zhuǎn)碼:格式轉(zhuǎn)換、信息綜合以及內(nèi)容注入
【格式轉(zhuǎn)換】
格式轉(zhuǎn)換是指將數(shù)據(jù)從一種格式轉(zhuǎn)換成另一種格式,使之可以被客戶端査看。通過HTML到WML的轉(zhuǎn)換,無線設(shè)備就可以訪問通常供桌面客戶端査看的文檔了。通過慢速連接訪問Web頁(yè)面的客戶端并不需要接收高分辨率圖像,如果通過格式轉(zhuǎn)換降低圖像分辨率和顏色來減小圖像文件大小的話,這類客戶端就能更容易地査看圖像比較豐富的頁(yè)面了
格式轉(zhuǎn)換可以由內(nèi)容協(xié)商首部集來驅(qū)動(dòng),但也能由User-Agent首部來驅(qū)動(dòng)。注意,內(nèi)容轉(zhuǎn)換或轉(zhuǎn)碼與內(nèi)容編碼或傳輸編碼是不同的,后兩者一般用于更高效或安全地傳輸內(nèi)容,而前兩者則可使訪問設(shè)備能夠査看內(nèi)容
【信息綜合】
從文檔中提取關(guān)鍵的信息片段稱為信息綜合(information synthesis),這是一種有用的轉(zhuǎn)碼操作。這種操作的例子包括根據(jù)小節(jié)標(biāo)題生成文檔的大綱,或者從頁(yè)面中刪除廣告和商標(biāo)
根據(jù)內(nèi)容中的關(guān)鍵字對(duì)頁(yè)面分類是更精細(xì)的技術(shù),有助于總結(jié)文檔的精髓。這種技術(shù)常用于Web頁(yè)面分類系統(tǒng)中,比如門戶網(wǎng)站的Web頁(yè)面目錄
【內(nèi)容注入】
前面描述的兩類轉(zhuǎn)碼通常會(huì)減少Web文檔的內(nèi)容,但還有另一類轉(zhuǎn)換會(huì)增加文檔的內(nèi)容,即內(nèi)容注入轉(zhuǎn)碼。內(nèi)容注入轉(zhuǎn)碼的例子有自動(dòng)廣告生成器和用戶追蹤系統(tǒng)
設(shè)想一下,一個(gè)能往途經(jīng)的每個(gè)HTML頁(yè)面中自動(dòng)添加廣告的廣告植入轉(zhuǎn)碼器是多么的誘人,當(dāng)然也很煩人。這類轉(zhuǎn)碼操作只能動(dòng)態(tài)進(jìn)行——它必須即時(shí)添加與當(dāng)前的特定用戶有關(guān),或針對(duì)特定用戶的廣告。也可以構(gòu)建用戶追蹤系統(tǒng),在頁(yè)面中動(dòng)態(tài)增加內(nèi)容,用于收集用戶査看頁(yè)面和客戶端瀏覽方式的統(tǒng)計(jì)信息
【轉(zhuǎn)碼與靜態(tài)預(yù)生成的對(duì)比】
轉(zhuǎn)碼的替代做法是在Web服務(wù)器上建立Web頁(yè)面的不同副本,例如一個(gè)是HTML,一個(gè)是WML;一個(gè)圖像分辨率高,一個(gè)圖像分辨率低;一個(gè)有多媒體內(nèi)容,一個(gè)沒有。但是,這種方法不是很切合實(shí)際,原因很多:某個(gè)頁(yè)面中的任何小改動(dòng)都會(huì)牽扯很多頁(yè)面,需要很多空間來存儲(chǔ)各頁(yè)面的不同版本,而且使頁(yè)面編目和Web服務(wù)器編程(以提供正確的版本)變得更加困難。有些轉(zhuǎn)碼操作,比如廣告插入(尤其是定向廣告插入),就不能靜態(tài)實(shí)現(xiàn)——因?yàn)椴迦胧裁磸V告和請(qǐng)求頁(yè)面的用戶有關(guān)
對(duì)單一的根頁(yè)面進(jìn)行即時(shí)轉(zhuǎn)換,是比靜態(tài)的預(yù)生成更容易的解決方案。但這樣會(huì)在提供內(nèi)容時(shí)增加時(shí)延。不過有時(shí)候其中一些計(jì)算可以由第三方進(jìn)行,這樣就減少了Web服務(wù)器上的計(jì)算負(fù)荷——比如可以由代理或緩存中的外部Agent完成轉(zhuǎn)換
下圖顯示了在代理緩存中進(jìn)行的轉(zhuǎn)碼
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。