?
This document uses PHP Chinese website manual Release
在HTTP中,內(nèi)容協(xié)商是用于在相同URI處為資源提供不同表示的機(jī)制,以便用戶代理可以指定哪一個最適合用戶(例如,文檔的哪種語言,哪種圖像格式或哪些內(nèi)容編碼)。
一個特定的文檔被稱為資源。當(dāng)客戶想要獲得它時(shí),它會使用它的URL來請求它。服務(wù)器使用此URL來選擇它提供的變體之一 - 每個變體稱為表示 - 并將此特定表示形式返回給客戶機(jī)。整體資源以及每個表示都有一個特定的URL。在調(diào)用資源時(shí)如何選擇特定的表示形式取決于內(nèi)容協(xié)商,并且客戶端和服務(wù)器之間有多種協(xié)商方式。
通過以下兩種機(jī)制中的一種來確定最適合的表示:
客戶端的特定HTTP頭(服務(wù)器驅(qū)動的協(xié)商或主動協(xié)商),這是協(xié)商特定種類資源的標(biāo)準(zhǔn)方式。
服務(wù)器(代理驅(qū)動的協(xié)商或反應(yīng)式協(xié)商)提供的300
(多選)或406
(不可接受的)HTTP響應(yīng)代碼,用作后備機(jī)制。
多年來,已經(jīng)提出了其他內(nèi)容協(xié)商提議,如透明內(nèi)容協(xié)商和Alternates
標(biāo)題。他們未能獲得牽引力而被拋棄。
在服務(wù)器驅(qū)動的內(nèi)容協(xié)商或主動式內(nèi)容協(xié)商中,瀏覽器(或任何其他類型的用戶代理)會發(fā)送多個HTTP標(biāo)頭以及URL。這些標(biāo)題描述了用戶的首選。服務(wù)器使用它們作為提示,并且內(nèi)部算法選擇向客戶端提供最佳內(nèi)容。該算法是特定于服務(wù)器的,并未在標(biāo)準(zhǔn)中定義。例如,請參閱Apache 2.2協(xié)商算法。
HTTP / 1.1標(biāo)準(zhǔn)定義了啟動服務(wù)器驅(qū)動的協(xié)商(標(biāo)準(zhǔn)報(bào)頭的列表Accept
,Accept-Charset
,Accept-Encoding
,Accept-Language
)。雖然嚴(yán)格來說User-Agent
不在此列表中,但它有時(shí)也用于發(fā)送所請求資源的特定表示,盡管這不被認(rèn)為是一種好的做法。服務(wù)器使用Vary
頭來指示它實(shí)際用于內(nèi)容協(xié)商的頭(或更確切地說是關(guān)聯(lián)的響應(yīng)頭),以便緩存可以最佳地工作。
除此之外,還有一個實(shí)驗(yàn)性的建議是在可用標(biāo)題列表中添加更多標(biāo)題,稱為客戶端提示。客戶端提示通知用戶代理運(yùn)行的設(shè)備類型(例如,如果它是臺式計(jì)算機(jī)或移動設(shè)備)。
即使服務(wù)器驅(qū)動的內(nèi)容協(xié)商是就資源的特定表示達(dá)成一致的最常見方式,但它有幾個缺點(diǎn):
服務(wù)器不具有瀏覽器的全部知識。即使使用客戶端提示擴(kuò)展,它也不完全了解瀏覽器的功能。與客戶做出選擇的被動內(nèi)容協(xié)商不同,服務(wù)器選擇總是有些隨意。
客戶端的信息非常詳細(xì)(HTTP / 2頭壓縮緩解了這個問題)和隱私風(fēng)險(xiǎn)(HTTP指紋)
隨著給定資源的多個表示被發(fā)送,共享緩存效率較低,服務(wù)器實(shí)現(xiàn)更為復(fù)雜。
Accept
頭該Accept
標(biāo)題列出了MIME類型的媒體資源代理愿意處理。它是以逗號分隔的MIME類型列表,每個列表都與質(zhì)量因子相結(jié)合,該參數(shù)指示不同MIME類型之間的相對偏好程度。
Accept
頭是由瀏覽器,或任何其它用戶代理限定,并且可以根據(jù)環(huán)境而變化,像取HTML頁面或圖像,視頻,或腳本:提取在輸入的地址的文檔時(shí)它是不同桿或元件經(jīng)由連接<img>
,<video>
或<audio>
元件。瀏覽器可以自由使用他們認(rèn)為最合適的標(biāo)題的值; 常見瀏覽器默認(rèn)值的詳盡列表可用。
Accept-CH
頭這是名為Client Hints的實(shí)驗(yàn)性技術(shù)的一部分,目前僅在Chrome 46及更高版本中實(shí)施
實(shí)驗(yàn)Accept-CH
列出了服務(wù)器可用于選擇適當(dāng)響應(yīng)的配置數(shù)據(jù)。有效值是:
值 | 含義 |
---|---|
DPR | 指示客戶端的設(shè)備像素比率。 |
視口寬度 | 指示CSS像素中的布局視口寬度。 |
寬度 | 指示物理像素中的資源寬度(換句話說,是圖像的固有大?。?。 |
Accept-Charset
頭Accept-Charset
標(biāo)題指示到什么樣的字符編碼由用戶代理理解服務(wù)器。傳統(tǒng)上,它針對瀏覽器的每個區(qū)域設(shè)置為不同的值,例如ISO-8859-1,utf-8;q=0.7,*;q=0.7
西歐語言區(qū)域設(shè)置。
UTF-8現(xiàn)在得到了很好的支持,成為字符編碼的首選方式,并通過減少基于配置的熵來保證更好的隱私,大多數(shù)瀏覽器都忽略了Accept-Charset
標(biāo)題:Internet Explorer 8,Safari 5,Opera 11和Firefox 10已經(jīng)放棄這個標(biāo)題。
Accept-Encoding
頭Accept-Encoding
報(bào)頭定義內(nèi)容編碼的可接受的(支持的壓縮)。該值是br, gzip;q=0.8
指示編碼值的優(yōu)先級的q因子列表(例如:)。默認(rèn)值identity
是最低優(yōu)先級(除非另有聲明)。
壓縮HTTP消息是提高Web站點(diǎn)性能的最重要方式之一,它縮小了傳輸數(shù)據(jù)的大小并更好地利用了可用帶寬; 瀏覽器總是發(fā)送這個頭文件,服務(wù)器應(yīng)該被配置為遵守并使用壓縮。
Accept-Language
頭所述Accept-Language
報(bào)頭用于指示所述用戶的語言偏好。它是一個包含質(zhì)量因素的值列表(如:"de, en;q=0.7
“)。默認(rèn)值通常根據(jù)用戶代理圖形界面的語言設(shè)置,但大多數(shù)瀏覽器允許設(shè)置不同的語言首選項(xiàng)。
由于基于配置的熵增加,可以使用修改后的值來為用戶指紋,不建議對其進(jìn)行更改,并且網(wǎng)站不能相信此值以反映用戶的實(shí)際愿望。網(wǎng)站設(shè)計(jì)人員不能通過使用通過此標(biāo)頭進(jìn)行語言檢測而過于熱心,因?yàn)檫@會導(dǎo)致糟糕的用戶體驗(yàn):
他們應(yīng)該始終提供一種方法來克服服務(wù)器選擇的語言,例如通過在網(wǎng)站上提供語言菜單。大多數(shù)用戶代理為Accept-Language
標(biāo)題提供一個默認(rèn)值,根據(jù)用戶界面語言進(jìn)行調(diào)整,最終用戶通常不會對其進(jìn)行修改,或者不知道如何修改,或者無法完成,就像在網(wǎng)吧中一樣。
一旦用戶重寫了服務(wù)器選擇的語言,站點(diǎn)就不應(yīng)該再使用語言檢測,并應(yīng)該堅(jiān)持使用明確選擇的語言。換句話說,只有網(wǎng)站的入口頁面應(yīng)該使用這個頭文件選擇適當(dāng)?shù)恼Z言。
User-Agent
頭雖然這個標(biāo)題有合法的用途來選擇內(nèi)容,但依賴它來定義用戶代理支持哪些功能被認(rèn)為是不好的做法。
User-Agent
報(bào)頭標(biāo)識瀏覽器發(fā)送請求。該字符串可能包含空格分隔的產(chǎn)品標(biāo)記和注釋列表。
一個產(chǎn)品標(biāo)記 是一個后面是“ /
”和版本號一樣Firefox/4.0.1
的名字。用戶代理想要的可能有很多。一個注釋是括號分隔的一個任意字符串。顯然括號不能用在那個字符串中。評論的內(nèi)部格式不是由標(biāo)準(zhǔn)定義的,盡管多個瀏覽器在其中放置了幾個標(biāo)記,以' ;
' 分隔。
Vary
響應(yīng)報(bào)頭Accept-*
與客戶端發(fā)送的先前標(biāo)題相反,Vary
HTTP標(biāo)題是由Web服務(wù)器在其響應(yīng)中發(fā)送的。它表示服務(wù)器驅(qū)動的內(nèi)容協(xié)商階段服務(wù)器使用的標(biāo)頭列表。標(biāo)題是需要的,以便通知緩存的決策標(biāo)準(zhǔn),以便它可以重現(xiàn)它,允許緩存功能,同時(shí)防止向用戶提供錯誤的內(nèi)容。
' *
' 的特殊值意味著服務(wù)器驅(qū)動的內(nèi)容協(xié)商也使用信息中未傳送的信息來選擇適當(dāng)?shù)膬?nèi)容。
Vary
在HTTP的1.1版本中加入報(bào)頭和是必要的,以便允許高速緩存以適當(dāng)?shù)毓ぷ?。為了與服務(wù)器驅(qū)動的內(nèi)容協(xié)商一起工作,高速緩存需要知道服務(wù)器使用哪個標(biāo)準(zhǔn)來選擇傳輸?shù)膬?nèi)容。這樣,緩存就可以重播算法,并能夠直接提供可接受的內(nèi)容,而無需向服務(wù)器提出更多請求。顯然,通配符' *
'阻止了緩存的發(fā)生,因?yàn)榫彺娌恢浪澈笫鞘裁丛亍?/p>
服務(wù)器驅(qū)動的協(xié)商有一些缺點(diǎn):它不能很好地?cái)U(kuò)展。談判中使用的每個功能都有一個標(biāo)題。如果您想使用屏幕尺寸,分辨率或其他尺寸,則必須創(chuàng)建新的HTTP標(biāo)頭。發(fā)送標(biāo)題必須在每個請求上完成。這并不是問題很少,只有很少的標(biāo)題,但隨著它們的最終乘法,消息大小會導(dǎo)致性能下降。發(fā)送的報(bào)頭越精確,發(fā)送的熵就越多,允許更多的HTTP指紋識別和相應(yīng)的隱私問題。
從HTTP開始,協(xié)議允許另一種協(xié)商類型:代理驅(qū)動協(xié)商或反應(yīng)式協(xié)商。在這個協(xié)商中,當(dāng)面對不明確的請求時(shí),服務(wù)器發(fā)送一個包含指向可用替代資源鏈接的頁面。用戶被呈現(xiàn)資源并選擇要使用的資源。
不幸的是,HTTP標(biāo)準(zhǔn)沒有指定允許在可用資源之間進(jìn)行選擇的頁面格式,這阻止了輕松自動化該過程。除了回到服務(wù)器驅(qū)動的協(xié)商之外,這種方法幾乎總是與腳本一起使用,尤其是在JavaScript重定向的情況下:在檢查協(xié)商標(biāo)準(zhǔn)后,腳本執(zhí)行重定向。第二個問題是需要多一個請求才能獲取真實(shí)資源,從而減慢了用戶對資源的可用性。