内容协商

内容协商（）是超文本传输协议（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头将内容协商扩展为检索以前版本的资源。Memento: Adding Time to the Web .

RFC 7231未规定如何解决两难问题（例如在上面的例子中，如果服务器有英语的HTML页面和德语的GIF图像）。

 用户代理驱动 
代理驱动（或称被动）内容协商是通过用户代理中的算法执行，由用户代理在可能的变体中选择一项。这通常基于服务器提供的多种表示及元数据来执行。

简单总结它的工作原理：当一个用户代理向服务器提交请求时，服务器通知用户代理它可用的表示法及各个表示法的元数据（例如内容类型、质量、语言等）。然后用户代理将请求重新提交到选定的一种表示法的特定网址。这种方式使用户代理可以自动选择，用户代理也可提供选项使用户手动选择，以及用户可以直接选择、配置。更具体来说，服务器响应300 Multiple Choices或406 Not Acceptable（当服务器驱动时，用户代理提供了接受标准但服务器无法自动选择时）。虽然如此，但HTTP没有规定表示方法及元数据的格式，以及相应的选择机制。

 内容格式 
用户代理可以从网页服务器或API请求指定格式的数据，例如application/json或application/xml。

 参见 
 網頁伺服器
 HTTP压缩

 参考文献 

 外部链接 
 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

Category:HTTP