实体和编码
HTTP要确保它所承载的实体满足以下条件:
- 可以被正确的识别(通过Content-Type首部说明媒体格式,Content-Language首部说明语言),以便浏览器和其它客户端能正确处理内容。
- 可以被正确的解包(通过Content-Length首部和Content-Encoding首部)。
- 是最新的(通过实体验证码和缓存过期机制)
- 符合用户的需要(基于Accept系列的内容协商首部)
- 在网络上可以快速有效的传输(通过范围请求、差异编码以及其他数据压缩方法)
- 完整到达、未被篡改(通过传输编码首部和Content-MD5校验和首部)
为了实现以上目标,HTTP使用了完善的标签来描述承载内容的实体。
HTTP报文实体
HTTP报文实体由实体首部和实体主体构成。
实体首部
HTTP实体首部描述了HTTP报文的内容。HTTP/1.1版定义了以下10个基本字体首部字段。
- Content-Type: 实体中所承载对象的类型
- Content-Length: 实体的长度
- Content-Language: 实体的人类语言
- Content-Encoding: 对对象数据所做的变换(压缩)
- Content-Location: 一个备用位置,请求时可以通过它获得对象
- Content-Range: 如果这是部分实体,这个首部说明它是整体的哪个部分
- Content-MD5: 实体主体内容的校验和
- Last-Modified: 最后修改日期
- Expires: 实体数据将要失效的时间
- Allow: 该资源允许的各种请求方法,例如GET和HEAD
- ETag: 这份文档特定实例的唯一验证码。
- Cache-Control: 指出应该如何缓存文档。
实体主体
首部字段以一个空白的CRLF结束,随后就是实体主体的原始内容。不管内容是什么,文本或者二进制的、文档或图像、压缩的或者重编码、英语、法语或者日语,都紧随这个CRLF之后。
实体的大小:Content-Length
Content-Length首部指出报文中实体主体的字节大小。 除非使用了分块编码,否则Content-Length首部就是带有实体主体的报文必须使用的。
使用Content-Length首部是为了能够检测出服务器崩溃而导致的报文截尾,并对共享持久连接的多个报文进行正确分段。
缓存代理服务器通常不会为没有显示Content-Length首部的HTTP主体做缓存,以此来减小缓存以截尾报文的风险。
如果主体进行了编码或者压缩,Content-Length首部说明的就是编码或者压缩后的主体的字节长度,而不是未编码的原始主体的长度。
实体摘要
Content-MD5首部是在内容做了所有需要的编码之后,还没有做任何传输编码之前,计算出来的。
媒体类型和字符集
Content-Type首部字段说明了实体主体的MIME类型。
Content-Type首部说明的是原始实体主体的媒体类型,也就是内容编码之前的媒体类型。
Content-Type: text/html; charset=iso-8859-1
内容编码
Content-Encoding首部说明内容编码的方式。
- gzip
- compress
- deflate
- identity
Accept-Encoding首部说明了客户端可以使用的内容编码方式。
传输编码和分块编码
内容编码是对报文的主体进行的可逆变换。
传输编码也是作用在实体主体上的可逆变换,但是用它们是由于架构方面的原因,同内容的格式无关。
- 未知内容大小:通常某些服务器希望在获知内容大小之前就开始传输数据。
- 安全性
HTTP协议中定义了两个首部来描述和控制传输编码。
- Transfer-Encoding:告知接收方为了可靠的传输报文,已经对其进行编码。
- TE:用在请求首部中,告知服务器可以使用哪些传输编码扩展。如果是Accept-Transfer-Encoding就好了。
分块编码是一种Transfer-Encoding方式。分块编码把报文分割为若干个大小已知的块。块之间是紧挨着发送的,这样就不需要在发送之前就知道整个报文大小了。
分块编码是传输编码不是内容编码。
分块编码是相当简单的。它由起始的HTTP响应首部开始,随后就是一系列分块。每个分块包含一个长度值和该分块的数据。 长度值是十六进制并将CRLF与数分隔开。分块中的数据大小以字节计算,不包括长度值与数据之间的CRLF序列以及分块结尾的CRLF序列。最后一个块有点特别,它的长度值为0,表示主体结束。