内容长度
Content-Length 标头确定请求/响应正文的字节长度。如果您忽略指定 Content-Length 标头,HTTP 服务器将隐式添加 Transfer-Encoding: chunked 标头。 Content-Length 和 Transfer-Encoding 标头不应一起使用。接收方将不知道正文的长度,也无法估计下载完成时间。如果您确实添加了Content-Length 标头,请确保它以字节为单位匹配整个正文,如果不正确,则接收者的行为未定义。
Content-Length 标头不允许流式传输,但它对于希望支持部分内容服务的大型二进制文件很有用。这基本上意味着可恢复下载、暂停下载、部分下载和多宿主下载。这需要使用名为Range 的附加标头。这种技术称为Byte serving。
传输编码
Transfer-Encoding: chunked 的使用允许在单个请求或响应中进行流式传输。这意味着数据以分块的方式传输,不会影响内容的表示。
HTTP 客户端的正式用途是发送带有TE 标头字段的请求,该字段指定客户端愿意接受的传输编码类型。这并不总是发送,但大多数服务器假定客户端可以处理 chunked 编码。
chunked 传输编码更好地利用了持久的 TCP 连接,HTTP 1.1 默认假定为真。
内容编码
还可以压缩分块或非分块数据。这实际上是通过 Content-Encoding 标头完成的。
注意Content-Length 等于Content-Encoding 之后的正文长度。这意味着如果您对响应进行了 gzip 压缩,则长度计算将在压缩后进行。如果您想计算长度,则需要能够将整个正文加载到内存中(除非您在其他地方有该信息)。
使用分块编码进行流式传输时,压缩算法还必须支持在线处理。幸运的是,gzip 支持流压缩。我相信内容会先被压缩,然后再切成块。这样,块被接收,然后解压缩以获取真实内容。如果反过来,你会得到压缩流,然后解压缩会给我们块。这没有意义。
一个典型的压缩流响应可能有这些头:
Content-Type: text/html
Content-Encoding: gzip
Transfer-Encoding: chunked
从语义上讲,Content-Encoding 的用法表示“端到端”编码方案,这意味着只有最终客户端或最终服务器应该对内容进行解码。中间的代理不应该解码内容。
如果你想让中间的代理解码内容,正确使用的标头实际上是Transfer-Encoding 标头。如果 HTTP 请求具有 TE: gzip chunked 标头,则以 Transfer-Encoding: gzip chunked 响应是合法的。
但是这很少被支持。所以你现在应该只使用Content-Encoding进行压缩。
Chunked vs Store & Forward