HTTP 内容协商与转码

Gao
## 内容协商与转码 一个 URL 常常需要代表若干不同的资源。例如那种需要以多种语言提供其内容的网站站点 。 HTTP 提 供了内容协商方法,允许客户端和服务器作这样的决定。通过这些方法,单一的 URL 就可以代表不同的资源(比如,同一个网站页面的法语版和英语版)。这些不同的版本称 为变体。 ### 内容协商技术 共有 3 种不同的方法可以决定服务器上哪个页面最适合客户端: - 让客户端来选择 - 服务器自动判定 - 让中间代理来选 这 3 种技术分别称为 - 客户端驱动的协商 - 服务器驱动的协商 - 透明协商 | 技术 | 工作原理 | 优点 | 缺点 | | ---------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | | 客户端驱动 | 客户端发起请求,服务器发送可选项的列表,客户端选择 | 在服务器端的实现最容易。客户端可以选择最合适的内容 | 增加了时延:为了获得正确的内容,至少要发送两次请求 | | 服务器驱动 | 服务器检查客户端的请求首部集并决定提供哪个版本的页面 | 比客户端驱动的协商方式要快。 HTTP 提供了 q 值机制,允许服务器近似匹配,还提供了 Vary 首部供服务器告知下游的设备如何对请求估值 | 如果结论不是很明确(比如首部集不匹配),服务器要做猜测 | | 透明 | 某个中间设备(通常是缓存代理)代表客户端进行请求协商 | 免除了 Web 服务器的协商开销。比客户端驱动的协商要快 | 关于如何进行透明协商,还没有正式的规范 | ### 客户端驱动的协商 从实现原理上来说,服务器实际上有两种方法为客户端提供选项: - 一是发送回一个 HTML 文档,里面有到该页面的各种版本的链接和每个版本的描述信息; - 另一种方法是发送回 HTTP/1.1 响应时,使用 300 Multiple Choices 响应代码。客户端 浏览器 收到这种响应时,在前一种情况下,会显示一个带有链接的页面; 在后一种情况 下,可能会弹出对话窗口,让用户做选择。不管怎么样,决定是由客户端的浏览器用户 作出的。 ### 服务器驱动的协商 有以下两种机制可供 HTTP 服务器评估发送什么响应给客户端比较合适。 - 检查内容协商首部集。服务器察看客户端发送的 Accept 首部集,设法用相应的 响应首 部与之匹配。 - 根据其他(非内容协商)首部进行变通。例如,服务器可以根据客户端发送的 User-Agent 首部来发送响应。 #### 内容协商首部集 | 首部 | 描述 | | --------------- | -------------------------- | | Accept | 告知服务器发送何种媒体类型 | | Accept-Language | 告知服务器发送何种语言 | | Accept-Charset | 告知服务器发送何种字符集 | | Accept-Encoding | 告知服务器采用何种编码 | 注意,由于 HTTP 是无状态的协议(表示服务器不会在不同的请求之间追踪客户端 的偏好 ),所以客户端必须在每个请求中都发送其偏好信息。 #### 内容协商首部中的质量值 客户端可以发送下列形式的 Accept-Language 首部: ```http Accept-Language: en;q=0.5, fr;q=0.0, nl;q=1.0, tr;q=0.0 ``` 其中 q 值的范围从 0.0 ~ 1.0(0.0 是优先级最低的,而 1.0 是优先级最高的)。上面 列 出的那个首部,说明该客户端最愿意接收荷兰语(缩写为 nl)文档,但英语(缩 写为 en)文 档也行;无论如何,这个客户端都不愿意收到法语(缩写为 fr)或土耳 其语(缩写为 tr)的版 本。 #### 随其他首部集而变化 服务器也可以根据其他客户端请求首部集来匹配响应,比如 User-Agent 首部。 在这种情况下,没有 q 值机制可供查找“最近似”的匹配。服务器或者去找完全匹配,或者 简单地有什么就给什么,这取决于服务器的实现。 由于缓存需要尽力提供所缓存文档中正确的“最佳”版本,HTTP 协议定义了服务器在响应中 发送的 Vary 首部。这个首部告知缓存(还有客户端和所有下游的代理)服务器根据哪些首部 来决定发送响应的最佳版本。 #### Apache 中的内容协商 1. 使用 type-map 文件 可以在服务器的配置文件中设 置 handler 来说明 type-map 文件的后缀名。 ```apache AddHandler type-map .var ``` 这里给出一个 type-map 文件示例: ```apache URI: joes-hardware.html URI: joes-hardware.en.html Content-type: text/html Content-language: en URI: joes-hardware.fr.de.html Content-type: text/html;charset=iso-8859-2 Content-language: fr, de ``` 根据这个 type-map 文件, Apache 服务器就知道要发送 joes-hardware.en.html 给请求 英语版的客户端,发送 joes-hardware.fr.de.html 给请求法语版的客户端。 Apache 服务 器也支持质量值,具体信息请参阅它的文档。 2. 使用 MultiView 为了使用 MultiView,必须在网站目录下的 `access.conf` 文件中的适当小节 (<Directory>、 <Location>,或 <Files>)使用 OPTION 指令来启用它。 如果启用了 MultiView,而浏览器又请求了名为 joes-hardware 的资源,服务器就会查找 所有名字中含有 joes-hardware 的文件,并为它们创建 type-map 文件。服务器会 根据名 字猜测其对应的内容协商首部集。例如,法语版的 joes-hardware 应当含有 .fr。 #### 服务器端扩展 另一种在服务器端实现内容协商的方法是使用服务器端扩展 ### 透明协商 透明协商机制试图从服务器上去除服务器驱动协商所需的负载,并用中间代理来代表客户端 以使与客户端的报文交换最小化。假定代理了解客户端的预期,这样就可以代表客户端与服 务器协商(在客户端请求内容的时候,代理已经收到了客户端的预期)。为了支持透明内容协 商,服务器必须有能力告知代理,服务器需要检查哪些请求首部,以便对客户端的请求进行 最佳匹配。 HTTP/1.1 规范中没有定义任何透明协商机制,但定义了 Vary 首部。服务器在 响应中发送了 Vary 首部,以告知中间节点需要使用哪些请求首部进行内容协商。 代理缓存可以为通过单个 URL 访问的文档保存不同的副本。如果服务器把它们的决 策过程 传给缓存,这些代理就能代表服务器与客户端进行协商。缓存同时也是进行 内容转码的好 地方,因为部署在缓存里的通用转码器能对任意服务器,而不仅仅是 一台服务器传来的内 容进行转码。 #### 进行缓存与备用候选 对内容进行缓存的时候是假设内容以后还可以重用。然而,为了确保对客户端请求 回送的 是正确的已缓存响应,缓存必须应用服务器在回送响应时所用到的大部分决 策逻辑。 #### Vary 首部 HTTP 的 Vary 响应首部中列出了所有客户端请求首部,服务器可用这些首部来选择文档或 产生定制的内容(在常规的内容协商首部集之外的内容)。 例如,若所提供的 文档取决于 User-Agent 首部,Vary 首部就必须包含 User-Agent。 当新的请求到达时,缓存会根据内容协商首部集来寻找最佳匹配。但在把文档提供 给客户 端之前,它必须检查服务器有没有在已缓存响应中发送 Vary 首部。如果有 Vary 首部,那 么新请求中那些首部的值必须与旧的已缓存请求里相应的首部相同。因为服务器可能会根据 客户端请求的首部来改变响应,为了实现透明协商,缓存必须为每个已缓存变体保存客户端 请求首部和相应的服务器响应首部。 ### 转码 如果服务器没有能满足客户端需求的文档会怎么样呢?服务器可以给出一个错误响应。但理 论上,服务器可以把现存的文档转换成某种客户端可用的文档。这种选项称为转码。 #### 格式转换 格式转换是指将数据从一种格式转换成另一种格式,使之可以被客户端查看。 - 通过 HTML 到 WML 的转换,无线设备就可以访问通常供桌面客户端查看的文档了。 - 通过慢速连接访问 Web 页面的客户端并不需要接收高分辨率图像,如果通过格式转换降 低图像分辨率和颜色来减小图像文件大小的话,这类客户端就能更容易地查看图像比较丰 富的页面了。 格式转换可以由内容协商首部集来驱动,但也能由 User-Agent 首部来驱动。 #### 信息综合 从文档中提取关键的信息片段称为信息综合(information synthesis),这是一种有用的转 码操作。这种操作的例子包括根据小节标题生成文档的大纲,或者从页面中删除广告和商标 。 根据内容中的关键字对页面分类是更精细的技术,有助于总结文档的精髓。这种技术常用于 Web 页面分类系统中,比如门户网站的 Web 页面目录。 #### 内容注入 前面描述的两类转码通常会减少 Web 文档的内容,但还有另一类转换会增加文档的内容, 即内容注入转码。 内容注入转码的例子有自动广告生成器和用户追踪系统。 #### 转码与静态预生成的对比 转码的替代做法是在 Web 服务器上建立 Web 页面的不同副本,例如一个是 HTML,一个是 WML; 一个图像分辨率高,一个图像分辨率低; 一个有多媒体内容,一个没有。 对单一的根页面进行即时转换,是比静态的预生成更容易的解决方案。不过有时候其中一些 计算可以由第三方进行,这样就减少了 Web 服务器上的计算负荷——比如可以由代理或缓存 中的外部 Agent 完成转换。 ### 下一步计划 - HTTP 中的内容协商受到一些性能方面的限制。在各种变体中搜索合适的内容,或尽力“猜 测”最佳匹配,都会有很大开销。有没有什么办法能专注内容协商协议以使这个过程更高 效? RFC 2295 和 RFC2296 尝试着对这个问题进行了研究,以提供透明的 HTTP 内容协商 。 - HTTP 不是唯一需要进行内容协商的协议。在其他一些情况下,客户端也需要和服务器交 互以便获得对客户端请求来说最好的答案,流媒体和传真就是另外两个 例子。能否在 TCP/IP 应用层协议之上开发出通用的内容协商协议呢?内容协商工作组(Content Negotiation Working Group)就是专门为这个问题而成立的。这个工作组目前已经停止工 作了,不过它提出了若干个 RFC。 ### 更多信息 - http://www.ietf.org/rfc/rfc2616.txt RFC 2616,“Hypertext Transfer Protocol-HTTP/1.1”(“超文本传输协议 HTTP/1.1”),这 是 HTTP 协议的当前版本,也是 HTTP/1.1 的官方规范。这份规范行文流畅、 组织良好, 是份详实的 HTTP 参考文献。不过对那些希望学习 HTTP 背后的各种 概念和决策动机、弄 清理论与实践不同之处的读者来说,它就不是很理想了。我们希望本书能补足背后的这些概 念,使读者能更好地利用这份规范。 - http://www.ietf.org/rfc/rfc2295.txt RFC 2295,“Transparent Content Negotiation in HTTP”(“HTTP 中的透明内容协 商”), 这是一份备忘录,描述了建立在 HTTP 之上的透明内容协商协议。这份备忘录目前还是实验 性的。 - http://www.ietf.org/rfc/rfc2296.txt RFC 2296,“HTTP Remote Variant Selection Algorithm RVSA 1.0”(“HTTP 远程变体选择算 法 RVSA1.0”),这份备忘录描述了为特定的 HTTP 请求透明地选择“最佳”内容的算法。这份 备忘录目前还是实验性的。 - http://www.ietf.org/rfc/rfc2936.txt RFC 2936,“HTTP MIME Type Handler Detection”(“HTTP MIME 类型处理器检 测”),这份备 忘录描述了一种用来判定浏览器支持的 MIME 类型处理器的方法。如果 Accept 首部不够明 确的话,这种方法就能派上用场。 - http://www.imc.org/ietf-medfree/index.htm 这个链接指向内容协商(简称 CONNEG)工作组网站。该工作组专注于 HTTP、 传真和打印方 面的透明内容协商。这个工作组目前已停止工作。