HTTP Content-Length与分块传输
Content-Length
是HTTP 请求用来告知body实体大小的一个字段。
比如Content-Length:1076
表示 body数据量为1076B。
如果使用 gzip, 长度值为实际压缩后的大小,而非原始数据大小。
分块传输
分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由应用服务器发送给客户端应用的数据(通常数据量较大或者长度未告知,比如视频,文件文档,动态生成)可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。
使用Transfer-Encoding
的chunked
值表示数据以分块的形式发送,这种情况Content-Length
通常不赋值。
比如
Content-Length:null
Transfer-Encoding:chunked (接下来的body我要一块一块的传,每一块大小可能不一样,等我传到大小为0的块时,就没了)
优点
- HTTP分块传输编码允许服务器为动态生成的内容维持HTTP持久连接。通常,持久链接需要服务器在开始发送消息体前发送Content-Length消息头字段,但是对于动态生成的内容来说,在内容创建完之前是不可知的。[动态内容,content-length无法预知]
- 分块传输编码允许服务器在最后发送消息头字段。对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。没有分块传输编码时,服务器必须缓冲内容直到完成后计算头字段的值并在发送内容前发送这些头字段的值。[散列签名,需缓冲完成才能计算]
- HTTP服务器有时使用压缩 (gzip或deflate)以缩短传输花费的时间。分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完成压缩过程以得知压缩后数据的大小。[gzip压缩,压缩与传输同时进行]
传输方式
返回的消息被分为多个数据块, 每个数据块分为 长度
+数据
两部分以 CRLR(\r\n
)结尾。终止块以长度为0结尾
响应示例
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
Content-Length 可能引发的请求问题
- 大于实际值会超时响应
- 小于实际值会截断可能导致后续数据解析混乱
- 中文计算长度不一致导致大小差异。
如何知道请求图片或者视频的大小?
Content-Length
(单位 B)告知body 大小 [后台写 header时知道数据大小情况下]
Content-Length:1076(body的大小是1076B,你读取1076B就可以完成任务了)
Transfer-Encoding: null
Transfer-Encoding
设为chunked
时,通过分块传输来确定,适用于大数据传输 [后台可能无法告知资源大小,或者不愿意提前计算]
Content-Length:null
Transfer-Encoding:chunked (接下来的body我要一块一块的传,每一块大小可能不一样,等我传到大小为0的块时,就没了)
- 短链接结束就传递完成,适用于短数据。
Content-Length:null
Transfer-Encoding:null
Connection:close(我不知道大小,我也用不了chunked,啥时候我关了tcp连接,就说明传输结束了)