如果把 HTTP 报文想象成因特网货运系统中的箱子,那么 HTTP 实体就是报文中实际的货物。
常见的 HTTP/1.1 实体首部:
Content-Length 首部指示出报文中实体主体的字节大小。如果文本文件压缩了,Content-Length 首部就是压缩后的大小。
早期的 http 版本才用关闭连接来划定报文的结束。如果没有 Content-Length 的话,客户端无法区分到底是报文结束时正常的连接关闭,还是报文传输中服务器崩溃而导致的连接关闭。
Content-Length 首部对持久连接是必不可少的。如果响应通过持久连接传送,就可能有另一条 HTTP 响应紧随其后。客户端必须通过 Content-Length 首部知道报文在何处结束了。
HTTP 允许对实体字体的内容进行编码,比如可以使之更安全或者进行压缩节省空间。
尽管 HTTP 通常都是在像 TCP/IP 这样的可靠传输协议之上实现的,但是仍有可能早传输过程中被修改,比如有不兼容的转码代理或者中间代理有误。所以 HTTP 也会对实体主体部分实现校验和, 通过 Content-MD5 首部发送实体主体运行的 MD5 算法结果。
Content-Type 的值是标准化的 MIME 类型
媒体类型中有个 multipart (多部分) 类型,HTTP 也支持多部分主体,通常只用两种情形:
- 提交填写好的表单(文件上传)
- 作为承载若干文档片段的范围响应
HTTP 应用程序有时在发送之前需要对内容进行编码。比如压缩文件
- 网站服务器生成原始响应报文,其中有原始的 Content-Type 和 Content-Length 首部
- 内容编码服务器创建编码后的报文。编码后的报文有同样的 Content-Type 但 Content-Length 可能不同(比如主体压缩)
- 接收程序得到编码后的报文,进行解码,获得原始报文。
HTTP 定义了一些标准的内容编码类型,并允许用扩展编码的形式添更多的编码。
客户端会通过 Accept-Encoding 首部告诉服务器自己支持哪些编码方式。客户端可以给每种编码附带 Q (质量)值参数来说明编码的优先级。
传输编码也是作用在实体主体上的可逆变换。与内容格式无关,使用传输编码是为了改变报文中的数据在网络上传输的方式。
HTTP 协议中只定义了两个首部来描述和控制传输编码。
-
Transfer-Encoding,告知接收方为了可靠的传输报文,已经对其进行了何种编码。
-
TE,用在请求首部中,告知服务器可以使用哪些传输编码扩展。
分块编码是把报文分割为若干个大小已知的块。块之间是紧挨发送的,这样就不需要在发送之前知道整个报文的大小。
如果客户端和服务器之久不是用的持久连接,客户端可以通过服务器主动关闭连接来知道文件传输结束,不用提前知道主体长度。
可以到使用了持久连接,一条连接上可以传输多个报文,这样就无法判断每一条报文是到哪里结束。所以必要通过 Content-Length 首部告知。
分块编码很好的解决了这个问题,分块编码就是把报文主体打成多个块发送,最后一个块的长度为 0 ,以此表示主体结束。