当我关注到 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 的一个有力工具,而且也可以创造性的应用于其余地方。