内容协商 (Content Negotiation)

大多数响应包含一个实体,此实体包含人类用户能理解的信息。通常,希望提供给用户相应于请求最容易得到的实体。对服务器和缓存来说,不幸的是,并不是所有的用户都对这个最容易得到的实体有喜好,并且并不是所有的用户代理(如web浏览器)都能一致的呈现这些实体。所以,HTTP提供了一些“内容协商”机制 — 当有多个可得的表现形式的时候,对特定的响应选择最好的表现形式的处理过程。

注意:没有称做“格式协商”(译注:“格式”指的是“媒体类型”)的,因为可替换的表现形式可能会同原来的有相同的媒体类型,只是利用了此媒体类型不同的性质,例如一种不同的语言。

任何包含一个实体主体的响应包括错误响应都可能会受协商的支配。

有两种类型的内容协商在HTTP中:服务器驱动协商和代理驱动协商。这两种类型的协商具有正交性并且能被单独使用或联合使用。一个联合使用方法的协商会被叫做透明协商,当缓存利用代理驱动协商的信息的时候,此代理驱动协商的信息被为后续请求提供服务器驱动协商的源服务器提供。

一、 服务器驱动协商(Server-driven Negotiation)

如果响应的最好的表现形式的选择是通过服务器上的算法来实现,那么这种方式的协商称做服务器驱动协商。选择是基于响应可得的表现形式(根据不同的维度,响应会不同;例如,语言,内容编码,等等)和请求消息里特定的头域或关于请求的其他信息(如:网络客户端的地址)。

服务器驱动协商是有优点的,当从可行的表现形式里进行选择的算法对用户代理进行描述是比较困难的时候(译注:代理驱动协商),或者当服务器期望发送“最好的猜测”给客户端而只通过一个响应(以避免后续请求的回路(一个请求会返回一个响应)延迟如果此“最好的猜测“对用户适合的时候)的时候。为了改善服务器的猜测,用户代理应该包含请求头域(Accept,Accept-Language,Accept-Encoding,等等),这些头域能描述它对响应的喜好。

服务驱动协商有如下缺点:

  1. 对服务器不可能确切的决定对用户来说什么是最好的,因为那需要对用户代理和用户对此响应目的的全面理解(如:用户到底想把响应展示到屏幕还是打印到纸上?)。
  2. 使用户代理描述请求里的能力是非常无效的(假设只有响应的一小部分有多个表现形式)还有会侵犯用户的隐私。
  3. 使源服务器的实现变得复杂,也对为请求产生响应的算法实现变得复杂。
  4. 可能会限制公有缓存(public cache)为多个客户请求利用相同响应的能力

HTTP/1.1包含下面的请求头域来使服务器驱动协商启动,这些请求头域描述了用户代理的能力和用户喜好:Accept,Accept-Charset,Accept-Encoding,Accept-Language,和User-Agent。然而,一些源服务器并不只局限于这些维度,这些服务器能基于请求的任何方面来让响应不同,这些方面包括请求头域之外的信息或在此规范里没有定义的扩展头域。

Vary头域能被用来表达服务器选择表现形式(representation)利用的参数,表现形式受服务器驱动协商的支配。

Accept: Which media types are acceptable for the response, such as “application/json,” “application/xml,” or a custom media type such as "application/vnd.example+xml"
Accept-Charset: Which character sets are acceptable, such as UTF-8 or ISO 8859-1.
Accept-Encoding: Which content encodings are acceptable, such as gzip.
Accept-Language: The preferred natural language, such as “en-us”.
二、代理驱动协商 (Agent-driven Negotiation)

对代理驱动协商来说,响应的最好表现形式的选择被用户代理执行,这在接收到源服务器一个初始的响应后。选择是基于响应的一系列可得的表现形式,这些表现形式被包含在初始响应的头域或初始响应的实体主体(entity-body)里,每个表现形式被一个属于自己的URI指定。从这些表现形式中选择可能被自动执行(如果用户代理有能力这样做)或者被用户从超文本连接菜单中手工选择。

代理驱动协商是有优点的,当响应可能会根据一般用途的维度(如:类型,语义,编码)而不同的时候,当源服务器不能通过查看请求而判定用户代理能力的时候,当共有缓存(public cache)被用来分派服务器的承载和减少网络使用的时候。

代理驱动协商也同样存在需要第二次请求而获得最好表现形式的缺点。第二次请求只有当缓存被使用时才是有效率的。另外,此规范没有定义用户代理自动选择表现形式的机制,所以不能防止任何这样的机制被用于HTTP/1.1

HTTP/1.1定义了300(多个选择)和406(不接受的)状态响应,当使用代理驱动协商时服务器不能或不愿意利用服务器驱动协商来提供一个不同的响应的是时候。

三、 透明协商(Transparent Negotiation)

透明协商是服务器驱动协商和代理驱动协商的结合体。当一个缓存被提供了构成响应的一系列可得的表现形式(就像在代理驱动协商里的响应一样)并且维度的差异能完全被缓存理解,那么此缓存变得有能力代表源服务器为那个资源的后续请求去执行服务器驱动协商。

透明协商的优点在于它能分发源服务器的协商工作并且能移去代理驱动协商的第二次请求的延迟,因为缓存能正确的猜测到合适的响应。

此规范没有定义透明协商的机制,所以,它不能防止任何这样的机制被用于HTTP/1.1。

ASP.NET Web API支持内容协商: 客户端和服务器可以一起从API返回的数据,以确定正确的格式. 我们提供了默认的XML支持, JSON的, 和表格的URL编码格式, 你可以扩展这种支持,通过添加自己的格式化, 甚至取代默认内容的谈判策略.

时间: 2024-12-07 11:03:50

内容协商 (Content Negotiation)的相关文章

Asp.Net Web API 2第十四课——Content Negotiation(内容协商)

原文:Asp.Net Web API 2第十四课--Content Negotiation(内容协商) 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET Web API如何实现内容协商. HTTP规范(RFC 2616)将内容协商定义为"在有多个表现可用时,为一个给定的响应选择最佳表现的过程".在HTTP中内容协商的主要机制是以下请求报头:

漫游 HTTP/2

HTTP 是什么 首先我们要明白 HTTP 是什么.HTTP 是一个基于 TCP/IP 的应用层通信协议,它是客户端和服务端在互联网互相通讯的标准.它定义了内容是如何通过互联网进行请求和传输的.HTTP 是在应用层中抽象出的一个标准,使得主机(客户端和服务端)之间的通信得以通过 TCP/IP 来进行请求和响应.TCP 默认使用的端口是80,当然也可以使用其它端口,比如 HTTPS 使用的就是 443 端口. HTTP/0.9 - 单行协议 (1991) HTTP 最早的规范可以追溯到 1991

每一个web开发者都应该了解的HTTP/2

自从我写了上一篇博文之后,就再也找不到空闲时间写文章了.今天我终于可以抽出时间写一些关于 HTTP 的东西. 我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务. 在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们应该怎么使用它. HTTP 是什么 首先我们要明白 HTTP 是什么.HTTP 是一个基于 TCP/IP 的应用层通信协议,它是客户端和服务端在互联网互相通讯的标准.它定义了内容是如何通过

【ASP.NET Web API教程】6.3 内容协商

原文:[ASP.NET Web API教程]6.3 内容协商 本文是Web API系列教程的第6.3小节 6.3 Content Negotiation 6.3 内容协商 摘自:http://www.asp.net/web-api/overview/formats-and-model-binding/content-negotiation By Mike Wasson|May 20, 2012 作者:Mike Wasson | 日期:2012-3-20 This article describe

Java RESTful Web Service实战(第2版) 2.6 内容协商

2.6 内容协商 一个资源可以有不同格式的表述,表述(即响应实体)的内容是人类可识别的信息,服务器很难使用一种表述来适应所有用户.conneg(HTTP Content Negotiation,内容协商)是指在服务器提供的多种表述中,为特定的请求选择最好的一种表述的处理过程.那么什么是最好,又怎样做到最好呢?服务器和客户端/浏览器之间往复通信来协商用于交换数据的内容格式等信息,达成一致即为最好.内容协商定义在RFC2616的第12节(http://www.w3.org/Protocols/rfc

MIME Type 引出的两难困境

mime 一切从一个糟糕的浏览器开始,它完全不支持 XHTML. 什么是 MIME Type? 为什么这么说呢?首先,我们要了解浏览器是如何处理内容的.在浏览器中显示的内容有 HTML.有 XML.有 GIF.还有 Flash--那么,浏览器是如何区分它们,绝对什么内容用什么形式来显示呢?答案是 MIME Type,也就是该资源的媒体类型. 媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的,例如: Content-Type

我所理解的RESTful Web API [设计篇]

<我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建REST风格的Web服务是最近两三年风行的潮流,所以很多人以为REST是一个事物.而事实却是:REST自其诞生之日起到现在(2014年)已经有14年了,它为什么叫这么一个"奇怪"的名字呢? 目录 一.为什么叫这个"奇怪"的名字?二.采用URI标识资源 二.采用URI标识

《Spring 5 官方文档》18. Web MVC 框架(十一)

18.16.6 Content Negotiation You can configure how Spring MVC determines the requested media types from the request. The available options are to check the URL path for a file extension, check the "Accept" header, a specific query parameter, or t

Java RESTful Web Service实战(第2版)

Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著 图书在版编目(CIP)数据 Java RESTful Web Service实战 / 韩陆著. -2版. -北京:机械工业出版社,2016.7 (Java核心技术系列) ISBN 978-7-111-54213-1 Ⅰ. J-   Ⅱ. 韩-   Ⅲ. JAVA语言-程序设计   Ⅳ. TP312 中国版本图书馆CIP数据核字(2016)第156331号 Java RESTful Web Servi