5月阅读周·HTTP权威指南:内容协商与转码之服务器驱动的协商篇
引言
HTTP(Hypertext Transfer Protocol,超文本传输协议)是在万维网上进行通信时所使用的协议方案。HTTP有很多应用,但最著名的是用于Web浏览器和Web服务器之间的双工通信。
《HTTP权威指南》一书将HTTP中一些互相关联且常被误解的规则梳理清楚,并编写了一系列基于各种主题的章节介绍HTTP各方面的特性。纵观全书,对HTTP“为什么”这样做进行了详细的解释,而不仅仅停留在它是“怎么做”的。此外,这本书还介绍了很多HTTP应用程序正常工作所必需且重要的非HTTP技术。
这本书主要包括以下内容:
- 第一部分描述了Web的基础构件与HTTP的核心技术
- 第二部分重点介绍了Web系统的结构构造块:HTTP服务器、代理、缓存、网关以及机器人应用程序。
- 第三部分提供了一套用于追踪身份、增强安全性以及控制内容访问的技术和技巧。
- 第四部分涵盖HTTP报文主体和Web标准,前者包含实际内容,后者描述并处理主体内容。
- 第五部分介绍了发布和传播Web内容的技巧。
- 第六部分是一些很有用的参考附录,以及相关技术的教程。
内容协商与转码
一个URL常常需要代表若干不同的资源。例如那种需要以多种语言提供其内容的网站站点。如果某个站点(比如Joe的五金商店这样的站点)有说法语的和说英语的两种用户,它可能想用这两种语言提供网站站点信息。
对于特定的URL来说,服务器还可以根据其他原则来决定发送什么内容给客户端最合适。在有些场合下,服务器甚至可以自动生成定制的页面。比如,服务器可以为手持设备把HTML页面转换成WML页面。这类动态内容变换被称为转码。这些变换动作是HTTP客户端和服务器之间进行内容协商的结果。
内容协商技术
共有3种不同的方法可以决定服务器上哪个页面最适合客户端:让客户端来选择、服务器自动判定,或让中间代理来选。这3种技术分别称为客户端驱动的协商、服务器驱动的协商以及透明协商。
客户端驱动的协商
对于服务器来说,收到客户端请求时只是发回响应,在其中列出可用的页面,让客户端决定要看哪个,这是最容易的事情。很显然,这是服务器最容易实现的方式,而且客户端很可能选择到最佳的版本(只要列表中有让客户端选择的足够信息)。不利之处是每个页面都需要两次请求:第一次获取列表,第二次获取选择的副本。这种技术速度很慢且过程枯燥乏味,让用户厌烦。
从实现原理上来说,服务器实际上有两种方法为客户端提供选项:一是发送回一个HTML文档,里面有到该页面的各种版本的链接和每个版本的描述信息;另一种方法是发送回HTTP/1.1响应时,使用300 Multiple Choices响应代码。客户端浏览器收到这种响应时,在前一种情况下,会显示一个带有链接的页面;在后一种情况下,可能会弹出对话窗口,让用户做选择。不管怎么样,决定是由客户端的浏览器用户作出的。
除了增加时延并且对每个页面都要进行繁琐的多次请求之外,这种方法还有一个缺点:它需要多个URL:公共页面要一个,其他每种特殊页面也都要一个。因此,比如说原始的请求地址是www.joes-hardware.com@@, Joe的服务器可能会回复某个页面,该页面里面有到www.joes-hardware.com/english和www.joes-hardware.com/french的链接。如果客户端想加书签的话,是要加在原始的公共页面上呢,还是加在选中的页面上呢?如果用户想把这个网站推荐给他的朋友,是告知www.joes-hardware.com这个地址好呢,还是只告诉他们讲英语的朋友www.joes-hardware.com/english这个地址?
服务器驱动的协商
我们了解了客户端驱动的协商存在的若干缺点。大部分缺点都涉及客户端和服务器之间通信量的增长,这些通信量用来决定什么页面才是对请求的最佳响应。减少额外通信量的一种方法是让服务器来决定发送哪个页面回去,但为了做到这一点,客户端必须发送有关客户偏好的足够信息,以便服务器能够作出准确的决策。
内容协商首部集
两种首部的用途截然不同。实体首部集像运输标签,它们描述了把报文从服务器传输给客户端的过程中必须的各种报文主体属性。而内容协商首部集是由客户端发送给服务器用于交换偏好信息的,以便服务器可以从文档的不同版本中选择出最符合客户端偏好的那个来提供服务。
注意,由于HTTP是无状态的协议(表示服务器不会在不同的请求之间追踪客户端的偏好),所以客户端必须在每个请求中都发送其偏好信息。
如果两个客户端都发送了Accept-Language首部,描述它们感兴趣的语言信息,服务器就能够决定发送wwwx.xxx.com的何种版本给哪个客户端了。让服务器自动选择发送回去的文档,减少了往返通信的时延,这种时延是客户端驱动模型中无法避免的。
然而,假设某个客户端偏好西班牙文,那服务器应当回送哪个版本的页面呢?英语还是法语?服务器只有两种选择:猜测或回退到客户端驱动模型,问客户端选择哪个。假如这个西班牙人碰巧懂一点英语,他可能会选择英文页面,这不是最理想的,但它能解决问题。在这种情况下,这个西班牙人需要有办法传达更多与其偏好有关的信息,也就是他的确对英语略知一二,在没有西班牙语的时候,英语也行。
幸运的是,HTTP提供了一种机制,可以让与这个西班牙人情况类似的客户端更详细地描述其偏好。这种机制就是质量值(简称q值)。
内容协商首部中的质量值
HTTP协议中定义了质量值,允许客户端为每种偏好类别列出多种选项,并为每种偏好选项关联一个优先次序。例如,客户端可以发送下列形式的Accept-Language首部:
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)的版本。注意,偏好的排列顺序并不重要,只有与偏好相关的q值才是重要的。
服务器偶尔也会碰到找不到文档可以匹配客户端的任何偏好的情况。对于这种情况,服务器可以修改文档,也就是对文档进行转码,以匹配客户端的偏好。
随其他首部集而变化
服务器也可以根据其他客户端请求首部集来匹配响应,比如User-Agent首部。例如,服务器知道老版本的浏览器不支持JavaScript语言,这样就可以向其发送不含有JavaScript的页面版本。
在这种情况下,没有q值机制可供查找“最近似”的匹配。服务器或者去找完全匹配,或者简单地有什么就给什么,这取决于服务器的实现。
由于缓存需要尽力提供所缓存文档中正确的“最佳”版本,HTTP协议定义了服务器在响应中发送的Vary首部。这个首部告知缓存(还有客户端和所有下游的代理)服务器根据哪些首部来决定发送响应的最佳版本。
Apache中的内容协商
这里概括了著名的Web服务器Apache是如何支持内容协商的。网站的内容提供者,比如说Joe,要负责为Joe的索引页面提供不同的版本。Joe还必须把这些索引页面文件放在和站点相关的Apache服务器的适当目录下。用以下两种方式可以启用内容协商。
- 在网站目录中,为网站中每个有变体的URI创建一个type-map(类型映射)文件。这个type-map文件列出了每个变体和其相关的内容协商首部集。
- 启用MultiViews指令,这样会使Apache自动为目录创建type-map文件。
总结
服务器通过客户端请求的首部集来获得这方面的信息。
有以下两种机制可供HTTP服务器评估发送什么响应给客户端比较合适。
- 检查内容协商首部集。服务器察看客户端发送的Accept首部集,设法用相应的响应首部与之匹配。
- 根据其他(非内容协商)首部进行变通。例如,服务器可以根据客户端发送的User-Agent首部来发送响应。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)