內容協商
此條目翻譯自其他語言維基百科,需要相關領域的編者協助校對翻譯。 |
HTTP/HTTPS |
---|
版本 |
請求方法 |
報文主體 |
頭欄位 |
狀態碼 |
相關主題 |
內容協商(英語:Content negotiation)是超文字傳輸協定(HTTP)中定義的一個機制,它使同一個統一資源標誌符(URI)上的文件可以根據用戶代理中指定的適用資訊提供不同的版本。這種機制的傳統用法是提供GIF或PNG格式的圖像,為不支援顯示PNG圖像的瀏覽器(例如微軟Internet Explorer 4)提供GIF版本的圖像。
因此,一個資源可以有多種不同版本可用。例如,它可能有不同語言或不同多媒體格式的版本,或者其他用法。選擇最合適版本的一種方法是為用戶提供一個索引頁面,由他們選擇所需的版本。但在某些情況下,也可根據一些標準來自動選擇。
機制
HTTP提供了多種內容協商機制:伺服器驅動(或稱主動),用戶代理驅動(或稱被動),透明,及其他組合、配合。
伺服器驅動
伺服器驅動(或稱主動)內容協商是根據伺服器上執行的演算法來選擇幾種可能的變種。這通常基於用戶代理提供的可接受標準來決定。
簡單總結它的工作原理:當用戶代理向伺服器提交請求時,用戶代理通告伺服器它能理解的媒體類型以及評級。更具體來說,用戶代理在HTTP頭Accept
中列出和提供可接受的媒體類型及相應的質素評級。伺服器按照用戶代理所提供的這些參數選擇提供最適合用戶代理的資源版本。
作為其中的重要一環,瀏覽器在傳送每個請求時都會附上它偏好的表示方式。例如,瀏覽器可能表示它更希望看到德語,否則提供英語。瀏覽器在請求的頭中指明此偏好。例如僅要求(偏好)德語,瀏覽器可能是傳送:
Accept-Language: de
應注意的是,此偏好僅在其是多種表示法可選並且是其中之一時適用,並且因語言而異。
以一個更複雜的請求為例,瀏覽器已組態為接受德語和英語,但更偏好德語,並且接受幾種媒體類型,相較純文字或其他文字類型而言更偏好HTML,並且在媒體檔案方面更偏好GIF和JPEG,但也允許其他媒體類型作為最後的選擇:
Accept-Language: de; q=1.0, en; q=0.5 Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
除了按內容類型或語言完成的伺服器驅動的內容協商,還有一個Accept-Datetime
頭將內容協商擴充為檢索以前版本的資源。[1]
RFC 7231未規定如何解決兩難問題(例如在上面的例子中,如果伺服器有英語的HTML頁面和德語的GIF圖像)。
用戶代理驅動
代理驅動(或稱被動)內容協商是通過用戶代理中的演算法執行,由用戶代理在可能的變體中選擇一項。這通常基於伺服器提供的多種表示及元數據來執行。
簡單總結它的工作原理:當一個用戶代理向伺服器提交請求時,伺服器通知用戶代理它可用的表示法及各個表示法的元數據(例如內容類型、質素、語言等)。然後用戶代理將請求重新提交到選定的一種表示法的特定網址。這種方式使用戶代理可以自動選擇,用戶代理也可提供選項使用戶手動選擇,以及用戶可以直接選擇、組態。更具體來說,伺服器響應300 Multiple Choices或406 Not Acceptable(當伺服器驅動時,用戶代理提供了接受標準但伺服器無法自動選擇時)。雖然如此,但HTTP沒有規定表示方法及元數據的格式,以及相應的選擇機制。
內容格式
用戶代理可以從網頁伺服器或API請求指定格式的數據,例如application/json或application/xml。
參見
參考文獻
外部連結
- RFC 7231 — Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content – (Section 5.3: Content Negotiation)
- RFC 2295 — Transparent Content Negotiation in HTTP
- RFC 2296 — HTTP Remote Variant Selection Algorithm -- RVSA/1.0
- Apache Content Negotiation (頁面存檔備份,存於互聯網檔案館)
- Open source PHP content negotiation library (supports wildcards and q values) (頁面存檔備份,存於互聯網檔案館)
- Discussion about XHTML serving with content negotiation and browser concerns requiring this