HTTP实体数据

289 阅读6分钟

导言

还记得在前几篇中,我们其实已经介绍过HTTP报文了,但HTTP报文是由header和body组成的,前面我们主要讲的是header部分,所以我们开始来聊聊body中的数据结构。

HTTP实体数据

Content-Type

在Chrome浏览器开发中工具中,查看任一请求接口,我们都可以看到这个字段,不管是在请求或是响应中:

image.png

这个字段非常重要。为什么呢?

我们都知道HTTP是应用层协议,基于TCP/IP传输协议,而TCP/IP做的其实是真正的传输工作,而HTTP是基于它的,TCP/IP作为传输层协议,就像是快递公司,是运输快递的,它不关心里面具体是什么(违禁品除外),主要就是把商品从商家那里送到买家手上,不会动手拆快递。动手拆,如何拆,这就需要买家自己来做,就像是HTTP协议,这是它的工作,因为它是面向客户端,不仅要把数据完整的返回给客户端,还得告诉它,如何用。这就是Content-Type字段的功能。

类别
  • text: 如上图中有:text/plain表示的纯文本,text/html表示超文本文档,text/css表示样式表等等...

  • image:表示图片格式,有png,gif等

  • audio:音频,如audio/mp3

  • vidio:视频,如vidio/rmvb

  • application:数据格式不固定,可能是文本也可能是二进制,常用的有application/xml、application/pdf等

这里还有补充下,上图请求标头中content-type的值是application/x-protobuf,其实protobuf(prototype buffer)是Google提出的一种数据交换格式,是一套类似于JSON或XML的数据传输格式或规范,应用于不同应用或进程之间的通信。

它有如下特点:

  • 语言无关,平台无关:支持Java、c++、JavaScript等

  • 高效:比XML还小很多

  • 扩展性、兼容性好

编码

在请求标头中,还有个Accept-Encoding字段,比较常用的也就是上面列举的那三种:gzip, deflate, br

  • gzip:GNU zip压缩,也是最常用的一种压缩方式
  • deflate:zlib压缩格式
  • br:这个是专门为优化HTTP的一种压缩算法

在Chrome浏览器控制台网络请求资源大小列我们可以看到这个提示:100kB transferred over network, resource size 500kB,就是把资源压缩了。

我们在请求头中的Accept字段会定义出客户端可以理解的内容格式,而在响应头字段中则返回Content-Type表示请求响应返回的真实实体数据格式类型,如下图:

image.png

Accept-Encoding也是客户端可接受的压缩方式,Content-Encoding则是响应返回的实体数据的真实压缩方式。需要注意的是:这两个字段都并非必现。如果请求头中没有Accept-Encoding,则表示客户端不支持任何压缩模式,而如果响应头中没有Content-Encoding,则表示返回的实体数据未被压缩。

语言类型和编码

我们从上面是不是可以总结出规律,客户端一般通过Accept-x字段来表达自己希望返回的实体数据格式,而服务器响应返回Content-x来表示实体数据的真实类型。

同样,语言类型和编码也可以这样对应,如:

请求头Accept-Language对应响应头Content-Language字段;

请求头Accept-Charset对应响应头Content-Charset字段;

但如果你在浏览器下查看HTTP报文的话会发现,请求中不会发送Accept-Charset字段信息,响应中也不会有Content-Language,并且Content-Charset字段好像也没有,其实不是没有这个字段,只是字符集的信息合并到了Content-Type中了,而Content-Language确实是没有的,因为可以通过字符集来推断出来是哪种语言。Accept-Charset字段没有现代浏览器几乎支持了所有主流字符集,就没有放在请求头中。

字符集

字符集在刚开始还是比较混乱的,各个国家都不统一,我们汉语有GBK,BIG5,英语有ASCII,日语有Shift_JIS,同一个文字内容被GBK字符编码正常,换做ASCII可能就一团糟,乱码了。这样肯定不行,就需要在全球推出一个更大更健全的字符集编码库,可以正常编码出大部分主流语言的能力。而后Unicode和UTF-8之类的字符集就应运而生了。

Quality Factor

我们先来看个报文,红框里面q=0.8中的q的全称就是Quality Factor(权重系数)。

image.png

Accept-Language:zh-CN,zh;q=0.9,en;q=0.8

那Accept-Language字段的值代表什么含义呢?

首先说明的一点是符号问题:逗号的优先级要高于分号,也就是说每项是以逗号来结束的,逗号内的每个参数以分号隔开,例如zh;q=0.9,是属于同一项,要放在一起解释,不能分开。

其次q的最大值是1,最小值是0.01,默认1,如果是0,则表示拒绝。

要解释上面报文的含义,还得知道zh-CN,zh,en所表示的意思。en是英文,zh是中文,这个大类清楚了,那zh-CN和zh有什么区别呢?我们可以猜,zh肯定是大类,CN是小类,小类还有cmn(官话、国语),czh(徽州话)等,CN表示的就是中国大陆的官方语言,以中文简体为主,而cn就包含中文中文言文,简体,繁体等或各种的混合体,范围更大。

现在就明白了这句报文了:权重优先级最高的是zh-CN,默认1,最大值,其次是中文,权重0.9,再后面是英文,权重0.8,权重越高,表示客户端更希望的语言类别是什么。

Vary

先来看看Vary在报文中的展现,可能有多个,且仅在响应标头中:

image.png

我们刚在讲Quality Factor权重的时候知道,服务器会根据客户端期望的权重来处理,尽可能满足客户端的要求,但具体是如何计算的,可能各客户端算法都不一样,对我们来说是个黑盒。

这样Vary字段就给了我们一些信息,它表示的是服务器根据了客户端提供的哪些协商参数去计算处理了。当客户端请求报文中某些Accept字段发生变化的时候,响应报文中的Vary字段也会返回响应的变化。即使同一个URI Vary的值也可能不同,所以从某个角度,每次的Vary值可以算是请求的一个快照,在HTTP缓存的时候也会提到。