當我關注到 HTTP 層的時候,發現不少 CIer 對內容協商還不是很瞭解,下面咱們一塊兒來探討一下什麼是內容協商,以及如何在即將到來的 CodeIgniter 4 中使用他。php
簡而言之,內容協商是指客戶端和服務器端就響應的資源內容進行交涉,而後提供給客戶端最爲適合的資源。內容協商會以響應資源的語言、圖片類型和編碼方式等做爲判斷的基準(包含在請求頭中的某些 Accept
字段就是判斷的基準)。html
舉個例子,我用 Chrome 訪問 Mozilla 的站點,能夠看到下面的 HTTP 請求頭信息:web
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8數組
accept-encoding:gzip, deflate, sdch瀏覽器
accept-language:en-US,en;q=0.8服務器
這些 accept
信息告訴咱們瀏覽器所支持的格式,並提供這些格式的優先級信息(經過 q 的值來肯定優先級)。以上信息說明瀏覽器在全部支持的內容類型中更但願接收 text/html 類型的內容。因爲個人瀏覽器的語言設置是英語,因此 accept-language
請求頭表示我更喜歡美式英語(en-US)的頁面。app
很顯然,即便咱們不提供任何內容協商信息,Web 站點仍是能夠照常運行,而且咱們已經這樣作了不少年。然而事實上 Web 服務器能夠幫咱們處理某些形式的內容協商,咱們一般不太善於利用這一點,但並不意味着服務器不能處理這些信息。工具
內容協商有兩個很吸引人的用處,一個是用於那些支持多國語言的站點,另外一個是用於返回特定格式數據的 API 接口。this
是否是必需要使用內容協商呢?可能不必定,他也許是把雙刃劍,有些人提議不要使用他,也有些人認爲他就像切片面包同樣使人喜好。但若是你想用,那在 CodeIgniter 中使用內容協商也是很容易的。編碼
這裏我不會對內容協商做過多詳細的介紹(詳細介紹將寫到用戶手冊中),這個例子簡單介紹了內容協商是如何肯定輸出語言的。
class BaseController extends \CodeIgniter\Controller { protected $language; public function __construct(...$params) { parent::__construct(...$params); $supportedLangs = ['en-US', 'en', 'fr']; $this->language = $this->request->negotiate('language', $supportedLangs); } }
這個例子表示該站點能夠支持英語和法語,咱們將支持的語言賦值到 $supportedLangs
數組裏,預示着默認語言是美式英語,但也支持普通英語和法語,而後簡單調用 $negotiate->language()
方法,傳遞支持的語言類型,解析時就能識別正確的 HTTP 頭,而後按照數組裏定義的優先級順序,返回最匹配的結果。若是兩種語言都沒法匹配,就會使用數組中的第一個語言。
Negotiate 類中的 4 個協商方法分別爲:
media() 不一樣於一般的 Accept
請求頭,他能夠用來請求不一樣版本的 html/text,或者音頻支持,圖像支持,等等。
charset() 不一樣於 Accept-Charset
請求頭,若是沒有匹配的話,默認值爲 UTF-8。
encoding() 不一樣於 Accept-Encoding
請求頭,能夠決定任何客戶端支持使用的壓縮類型。
language() 不一樣於 Accept-Language
請求頭。
並非全部場景都用得着內容協商,但他倒是構建高質量 API 的一個有力工具,而且也可以創造性的應用於其餘地方。