计算机网络协议系列 - HTTP 协议篇:HTTP 报文首部之响应首部字段篇

- 1 min

计算机网络协议系列(四十)

实体首部字段

常见的实体首部字段如下表所示:

img

实体首部字段是包含在请求报文和响应报文中实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

1)Allow

该字段我们在前面介绍 OPTIONS 请求方法时提到过,用于通知客户端能够服务器针对 Request URL 指定资源能够支持的所有 HTTP 请求方法,当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回,与此同时还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。

2)Content-Encoding

Content-Encoding: gzip

该字段用于告知客户端服务器对实体的主体部分选用的内容编码方式(一般都是数据压缩方式)。主要有以下几种内容编码方式:

这些内容编码方式在介绍 Accept-Encoding 首部字段时已经提到过,这里不再赘述。Accept-Encoding 一般用于客户端在发起请求时声明自己可以支持的内容编码方式,通过该请求首部字段与服务器进行协商,然后服务器在 Content-Encoding 响应首部提供了实际采用的内容编码方式。

需要注意的是,服务器端并不强制要求一定使用哪种内容编码方式。具体采用哪种内容编码方式高度依赖于服务器端的设置,及其所采用的模块,比如 Nginx 配置文件的 http 模块配置块中有如下配置项:

gzip on;
gzip_disable "msie6";

表示 Nginx 服务器在处理 HTTP 请求时启用 gzip 格式编码,但是在 IE6 中会禁用此编码。

讲到这里我们还要澄清 Transfer-Encoding 与 Content-Encoding 之间的区别,前面我们讲到 Transfer-Encoding 也是用于指定报文主体传输编码方式,但是它是逐跳首部,即只在两个相邻节点间有效,它跟前面介绍的 TE 首部字段是一对,TE 也是逐跳首部,用于告知服务器客户端能够处理的编码方式和相对优先级,而 Content-Encoding 和 Accept-Encoding 是一对,都是端到端首部,在整个传输过程中有效。

注:关于逐跳首部和端到端首部会在本篇教程最后面补充介绍。

为了解释清楚这个过程,我们举例来说明:

假设 A 为服务器,D 为客户端,从 A 到 D 的路径为 A-B-C-D(B、C为中间节点,比如代理),所需传输的资源为 X。步骤如下:

(1)D 向 A 请求 X,并在请求报文中指明自己支持的编码方式为 gzip:

Accept-Encoding: gzip

(2)请求按路径传递到 A 处,A 将 X 用 gzip 编码进行压缩并发到 B 处,由 B 进行下一步转交,并在报文中指明使用的编码方式为 gzip;

Content-Encoding: gzip

(3)B 认为传给 C 时使用分块传输比较合理,就对 A 传过来的报文实体进行分块,并在报文中说明:

Content-Encoding: gzip
Transfer-Encoding: chunked

(4)C 收到 B 的报文,并根据 Transfer-Encoding: chunked 判断出 B 进行了分块传输,于是 C 对收到的各个分块进行重组,还原出完整的 X(注意此时的 X 还是被 gzip 压缩过的状态)。之后 C 不进行分块,直接将整个发送给D:

Content-Encoding: gzip

(5)D接收到响应报文,并根据 Content-Encoding: gzip 判断出报文实体已经被 gzip 压缩过了,于是对其进行解码,最终获得资源X。

3)Content-Language

该字段用于告知客户端实体主体使用的自然语言。

与之类似的还有一个 Accept-Language 请求首部字段,该字段也是客户端发起请求时声明的可以理解的自然语言,用于与服务器进行协商,然后服务器可以通过 Content-Language 告知协商结果,如果没有指明 Content-Language,那么默认地,文件内容是提供给所有语言的访问者使用的。

4)Content-Length

该字段表明实体主体部分的大小(单位是字节),对实体主体进行分块内容编码传输时,不能再使用 Content-Length 首部字段,即使用了 Transfer-Encoding: chunked 编码,否则其他情况下必须在响应首部中包含此字段。

5)Content-Location

该字段用于给出与报文主体部分相对应的 URL,和首部字段 Location 不同,Content-Location 表示的是报文主体返回资源对应的 URL。

6)Content-MD5

该字段用于检查报文主体在传输过程中是否保持完整,以及确认传输到达。

其实现过程如下:对报文主体执行 MD5 算法得到 128 位二进制数,再通过普通 Base64 编码后将结果写入 Content-MD5 字段值(由于 HTTP 首部无法记录二进制值,所以要通过 Base64 编码处理)。

但采用这种方法,对内容上偶发性改变无从查证,也无法检测出恶意篡改。因为内容如果能篡改,那么意味着 Content-MD5 值也可重新计算然后被篡改,所以处在接收阶段的客户端是无法意识到报文主体以及首部字段 Content-MD5 是已经被篡改的。

7)Content-Range

针对范围请求,在响应首部中使用该字段能告知客户端作为响应返回的实体的哪个部分符合范围请求,字段值以字节为单位,表示当前发送部分及整个实体大小:

Content-Range: bytes 5001-10000/10000

8)Content-Type

该字段表示实体主体内对象的媒体类型,和首部字段 Accept 一样,字段值用 type/subtype 形式赋值:

Content-Type: text/html; charset=UTF-8

显然,该字段和请求首部字段 Accept 是一对,Accept 字段用于客户端在发起请求时告知服务器自己能够处理的内容类型,以便和服务器进行协商,服务器则通过 Content-Type 响应首部字段告知客户端协商结果。

9)Expires

该字段将资源失效日期告知客户端,缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直保存。当超过指定时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

当首部字段 Cache-Control 有指定 max-age 指令时,比起首部字段 Expires,会优先处理 max-age 指令。后面我们介绍 HTTP 缓存时,还会继续介绍该首部字段。

10)Last-Modified

该字段指明资源最新修改的时间,一般来说,这个值就是请求 URL 指定资源被修改的时间。常常与 If-Modified-Since 字段结合使用,后面我们在介绍 HTTP 缓存时还会详细介绍该字段。

补充介绍:端到端首部与逐跳首部

HTTP 首部字段根据作用范围可以分为两种类型:

下面列举了 HTTP/1.1 中的逐跳首部,除此之外其它所有字段都属于端到端首部:

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora