码迷,mamicode.com
首页 > Web开发 > 详细

http内容协商

时间:2018-01-30 19:55:33      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:encoding   b2c   负载   门户   发布   lis   utf-8   部分   http首部   

概览
对于特定的URL来说,服务器可以根据一些原则来决定发送什么内容给客户端最合适。在有些场合下,服务器甚至可以自动生成定制的页面。比如,服务器可以为手持设备把HTML页面转换成WML页面。这类动态内容变换被称为转码。这些变换动作是HTTP客户端和服务器之间进行内容协商的结果
  共有3种不同的方法可以决定服务器上哪个页面最适合客户端:让客户端来选择、服务器自动判定,或让中间代理来选。这3种技术分别称为客户端驱动的协商、服务器驱动的协商以及透明协商
技术分享图片
1 客户端驱动
对于服务器来说,收到客户端请求时只是发回响应,在其中列出可用的页面,让客户端决定要看哪个,这是最容易的事情。很显然,这是服务器最容易实现的方式,而且客户端很可能选择到最佳的版本(只要列表中有让客户端选择的足够信息)。不利之处是每个页面都需要两次请求:第一次获取列表,第二次获取选择的副本。这种技术速度很慢且过程枯燥乏味,让用户厌烦
  从实现原理上来说,服务器实际上有两种方法为客户端提供选项:一是发送回一个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 这个地址?
2 服务器驱动
减少额外通信量的一种方法是让服务器来决定发送哪个页面回去,但为了做到这一点,客户端必须发送有关客户偏好的足够信息,以便服务器能够作出准确的决策。服务器通过客户端请求的首部集来获得这方面的信息
有以下两种机制可供HTTP服务器评估发送什么响应给客户端比较合适
1、检査内容协商首部集。服务器察看客户端发送的Accept首部集,设法用相应的响应首部与之匹配
2、根据其他(非内容协商)首部进行变通。例如,服务器可以根据客户端发送的User-Agent首部来发送响应
2.1 内容协商首部集
客户端可以用下面列出的HTTP首部集发送用户的偏好信息
首部           描述
Accept        告知服务器发送何种媒体类型
Accept-Language 告知服务器发送何种语言
Accept-Charset   告知服务器发送何种字符集
Accept-Encoding 告知服务器采用何种编码
[注意]这些首部与实体首部非常类似。不过,这两种首部的用途截然不同。实体首部集像运输标签,它们描述了把报文从服务器传输给客户端的过程中必须的各种报文主体属性。而内容协商首部集是由客户端发送给服务器用于交换偏好信息的,以便服务器可以从文档的不同版本中选择出最符合客户端偏好的那个来提供服务

服务器用下面列出的实体首部集来匹配客户端的Accept首部集
Accept首部    实体首部
Accept       Content-Type
Accept-Language Content-Language
Accept-Charset Content-Type
Accept-Encoding Content-Encoding
由于HTTP是无状态的协议,表示服务器不会在不同的请求之间追踪客户端的偏好,所以客户端必须在每个请求中都发送其偏好信息
如果两个客户端都发送了Accept-Language首部,描述它们感兴趣的语言信息,服务器就能够决定发送www.joes-hardware.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值才是重要的
服务器偶尔也会碰到找不到文档可以匹配客户端的任何偏好的情况。对于这种情况,服务器可以修改文档,也就是对文档进行转码,以匹配客户端的偏好
2.2 常见的http内容协商首部
Accept-Language: zh-cn,zh;q=0.5
  意思:浏览器支持的语言分别是中文和简体中文,优先支持简体中文。
  详解:
  Accept-Language表示浏览器所支持的语言类型;
  zh-cn表示简体中文;zh 表示中文;
  q是权重系数,范围 0 =< q <= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容,若没有指定 q 值,则默认为1,若被赋值为0,则用于提醒服务器哪些是浏览器不接受的内容类型。
技术分享图片
Accept-Encoding: gzip, deflate,br
  意思:浏览器支持的压缩编码是 gzip 和 deflate。
  详解:
  Accept-Encoding表示浏览器有能力解码的编码类型;
  gzip是 GNU zip 的缩写,它是一个 GNU 自由软件的文件压缩程序,也经常用来表示 gzip 这种文件格式。
  deflate是同时使用了 LZ77 算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。
br是Brotli,是开发一种全新的数据格式,可以提供比Zopfli高20-26%的压缩比。据谷歌研究,Brotli压缩速度同zlib的Deflate实现大致相同,而在Canterbury语料库上的压缩密度比LZMA和bzip2略大。
技术分享图片

响应首部
技术分享图片

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
  意思:浏览器支持的 MIME 类型分别是 text/html、application/xhtml+xml、application/xml 和 /,优先顺序是它们从左到右的排列顺序。
  详解:
  Accept表示浏览器支持的 MIME 类型;
  MIME的英文全称是 Multipurpose Internet Mail Extensions(多功能 Internet 邮件扩充服务),它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。
  text/html,application/xhtml+xml,application/xml 都是 MIME 类型,也可以称为媒体类型和内容类型,斜杠前面的是 type(类型),斜杠后面的是 subtype(子类型);type 指定大的范围,subtype 是 type 中范围更明确的类型,即大类中的小类。
  Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
  text/html表示 html 文档;
  Application:用于传输应用程序数据或者二进制数据;
  application/xhtml+xml表示 xhtml 文档;
  application/xml表示 xml 文档。
技术分享图片

  Accept-Charset: GB2312,utf-8;q=0.7,;q=0.7
  意思:浏览器支持的字符编码分别是 GB2312、utf-8 和任意字符,优先顺序是 GB2312、utf-8、

  详解:
  Accept-Charset告诉 Web 服务器,浏览器可以接受哪些字符编码;
  GB2312是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称GB0,由中国国家标准总局发布,1981年5月1日实施。GB2312 编码通行于中国大陆;新加坡等地也采用此编码。
  utf-8是 Unicode 的一种变长字符编码又称万国码,由 Ken Thompson 于1992年创建,现在已经标准化为 RFC 3629。
  表示任意字符编码,虽然 q 都是等于 0.7,但明确指定的 GB2312,utf-8 比 具有更高的优先级。
2.3 其他首部集
服务器也可以根据其他客户端请求首部集来匹配响应,比如User-Agent首部。例如,服务器知道老版本的浏览器不支持JavaScript语言,这样就可以向其发送不含有JavaScript的页面版本
在这种情况下,没有q值机制可供査找“最近似”的匹配。服务器或者去找完全匹配,或者简单地有什么就给什么,这取决于服务器的实现
由于缓存需要尽力提供所缓存文档中正确的“最佳”版本,HTTP协议定义了服务器在响应中发送的Vary首部。这个首部告知缓存,还有客户端和所有下游的代理,服务器根据哪些首部来决定发送响应的最佳版本

3 透明协商
透明协商机制试图从服务器上去除服务器驱动协商所需的负载,并用中间代理来代表客户端以使与客户端的报文交换最小化。假定代理了解客户端的预期,这样就可以代表客户端与服务器协商,在客户端请求内容的时候,代理已经收到了客户端的预期
为了支持透明内容协商,服务器必须有能力告知代理,服务器需要检査哪些请求首部,以便对客户端的请求进行最佳匹配。HTTP/1.1规范中没有定义任何透明协商机制,但定义了Vary首部。服务器在响应中发送了Vary首部,以告知中间节点需要使用哪些请求首部进行内容协商
代理缓存可以为通过单个URL访问的文档保存不同的副本。如果服务器把它们的决策过程传给缓存,这些代理就能代表服务器与客户端进行协商。缓存同时也是进行内容转码的好地方,因为部署在缓存里的通用转码器能对任意服务器,而不仅仅是一台服务器传来的内容进行转码
3.1 缓存与备用候选
对内容进行缓存的时候是假设内容以后还可以重用。然而,为了确保对客户端请求回送的是正确的已缓存响应,缓存必须应用服务器在回送响应时所用到的大部分决策逻辑
上面描述了客户端发送的Accept首部集,以及为了给每条请求选择最佳的响应,服务器使用的与这些首部集匹配的相应实体首部集。缓存也必须使用相同的首部集来决定回送哪个已缓存的响应
下图展示了涉及缓存的正确及错误的操作序列。缓存把第一个请求转发给服务器,并存储其响应。对于第二个请求,缓存根据URL査找到了匹配的文档。但是,这份文档是法语版的,而请求者想要的是西班牙语版的。如果缓存只是把文档的法语版本发给请求者的话,它就犯了错误
技术分享图片

因此,缓存也应该把第二条请求转发给服务器,并保存该URL的响应与“备用候选”响应。缓存现在就保存了同一个URL的两份不同的文档,与服务器上一样。这些不同的版本称为变体(variant)或备用候选(alternate)。内容协商可看成是为客户端请求选择最合适变体的过程
3.2 Varry首部
这里是浏览器和服务器发送的一些典型的请求及相应首部
技术分享图片

然而,如果服务器的决策不是依据Accept首部集,而是比如User-Agent首部的话,情况会如何?这不像听起来这么极端。例如,服务器可能知道老版本的浏览器不支持JavaScript语言,因此可能会回送不包含JavaScript的页面版本。如果服务器是根据其他首部来决定发送哪个页面的话,缓存必须知道这些首部是什么,这样才能在选择回送的页面时做出同样的逻辑判断
  HTTP的Vary响应首部中列出了所有客户端请求首部,服务器可用这些首部来选择文档或产生定制的内容(在常规的内容协商首部集之外的内容)。例如,若所提供的文档取决于User-Agent首部,Vary首部就必须包含User-Agent
  当新的请求到达时,缓存会根据内容协商首部集来寻找最佳匹配。但在把文档提供给客户端之前,它必须检査服务器有没有在已缓存响应中发送Vary首部。如果有Vary首部,那么新请求中那些首部的值必须与旧的已缓存请求里相应的首部相同。因为服务器可能会根据客户端请求的首部来改变响应,为了实现透明协商,缓存必须为每个已缓存变体保存客户端请求首部和相应的服务器响应首部,参见下图
技术分享图片

如果某服务器的Vary首部看起来像下面这样,大量不同的User-Agent和Cookie值将会产生非常多的变体:

Vary: User-Agent, Cookie
缓存必须为每个变体保存其相应的文档版本。当缓存执行査找时,首先会对内容协商首部集进行内容匹配,然后比较请求的变体与缓存的变体。如果无法匹配,缓存就从原始服务器获取文档
3.3 转码
我们已经讨论了一个机制,该机制可以让客户端和服务器从某个URL的一系列文档中挑选出最适合客户端的文档。实现这些机制的前提是,存在一些满足客户端需求的文档——不管是完全满足还是在一定程度上满足
然而,如果服务器没有能满足客户端需求的文档会怎么样呢?服务器可以给出一个错误响应。但理论上,服务器可以把现存的文档转换成某种客户端可用的文档。这种选项称为转码
下面列出了一些假设的转码
转换之前             转换之后
HTML文档           WML文档
高分辨率图像         低分辨率图像
彩×××像           黑白图像
有多个框架的复杂页面     没有很多框架或图像的简单文本页面
有Java小应用程序的HTML页面 没有Java小应用程序的HTML页面
有广告的页面         去除广告的页面

有3种类别的转码:格式转换、信息综合以及内容注入
3.3.1 格式转换
格式转换是指将数据从一种格式转换成另一种格式,使之可以被客户端査看。通过HTML到WML的转换,无线设备就可以访问通常供桌面客户端査看的文档了。通过慢速连接访问Web页面的客户端并不需要接收高分辨率图像,如果通过格式转换降低图像分辨率和颜色来减小图像文件大小的话,这类客户端就能更容易地査看图像比较丰富的页面了
格式转换可以由内容协商首部集来驱动,但也能由User-Agent首部来驱动。注意,内容转换或转码与内容编码或传输编码是不同的,后两者一般用于更高效或安全地传输内容,而前两者则可使访问设备能够査看内容
3.3.2 信息综合
从文档中提取关键的信息片段称为信息综合(information synthesis),这是一种有用的转码操作。这种操作的例子包括根据小节标题生成文档的大纲,或者从页面中删除广告和商标
根据内容中的关键字对页面分类是更精细的技术,有助于总结文档的精髓。这种技术常用于Web页面分类系统中,比如门户网站的Web页面目录
3.3.3 内容注入
前面描述的两类转码通常会减少Web文档的内容,但还有另一类转换会增加文档的内容,即内容注入转码。内容注入转码的例子有自动广告生成器和用户追踪系统
设想一下,一个能往途经的每个HTML页面中自动添加广告的广告植入转码器是多么的诱人,当然也很烦人。这类转码操作只能动态进行——它必须即时添加与当前的特定用户有关,或针对特定用户的广告。也可以构建用户追踪系统,在页面中动态增加内容,用于收集用户査看页面和客户端浏览方式的统计信息
3.3.4 转码与静态预生产的对比
转码的替代做法是在Web服务器上建立Web页面的不同副本,例如一个是HTML,一个是WML;一个图像分辨率高,一个图像分辨率低;一个有多媒体内容,一个没有。但是,这种方法不是很切合实际,原因很多:某个页面中的任何小改动都会牵扯很多页面,需要很多空间来存储各页面的不同版本,而且使页面编目和Web服务器编程(以提供正确的版本)变得更加困难。有些转码操作,比如广告插入(尤其是定向广告插入),就不能静态实现——因为插入什么广告和请求页面的用户有关
对单一的根页面进行即时转换,是比静态的预生成更容易的解决方案。但这样会在提供内容时增加时延。不过有时候其中一些计算可以由第三方进行,这样就减少了Web服务器上的计算负荷——比如可以由代理或缓存中的外部Agent完成转换
下图显示了在代理缓存中进行的转码
技术分享图片

http内容协商

标签:encoding   b2c   负载   门户   发布   lis   utf-8   部分   http首部   

原文地址:http://blog.51cto.com/focuslinux/2066971

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!