❕大文件传输
数据压缩:默认开启,通常是保底的。详见内容协商
request
Accept-Encodingheaderresponse
Content-Encodingheader
分块传输:response 化整为零
范围请求:request 化整为零。可以仅一个范围,也可以多个范围
以上四种方式不是互斥的,可以混合起来使用。
分块传输
一个 response 报文的 body 总长度,要么已知 Content-Length,要么未知 chunked。
# 报文里的 body 不是一次性全发过来,而是分成了许多的 chunks 块逐个发送
Transfer-Encoding: chunked分块传输时 body 的编码规则:length 和 chunked data,如下:

每个 chunk 包含两个部分:length 是 16 进制的数字,data 紧跟在 length 之后,最后也以 CRLF 结尾,但数据不包含 CRLF。
最后用一个 length 为 0 的 chunk 表示结束,即 0\r\n\r\n。其中,第一个 \r\n 表示 CRLF(回车换行),第二个 \r\n 表示正常 HTTP 报文中 header 和 body 的分隔空行。
需要说明的是,浏览器在收到分块传输的数据后,会自动按照规则去掉分块编码,重新组装好内容。若想看 server 发出的分块的原始报文形态,要用 Wireshark 抓包,或用 Telnet 手工发送请求。
范围请求
范围请求,range request,可以只获取部分数据,从而实现视频拖拽、断点续传、多段下载等。可以一次只请求一个范围,也可以一次请求“多个”范围。
范围请求,允许客户端在请求 header 里使用专用字段 Range 来表示只想获取文件的一部分。
Range: bytes=x-y
206 Partial Content
Content-Range: bytes x-y/length
Range: bytes=x-y, x1-y1
Content-Type: multipart/byteranges; boundary=xx
Range
Range格式是 bytes=x-y,其中 x 和 y 是以字节为单位的数据偏移量,且都可以省略。
在服务器收到 Range 字段后:
检查范围是否合法。若越界了,会返回状态码
416如果范围正确,便根据 Range 计算偏移量,读取文件的片段
206 Partial Content状态码Content-Rangeheader 告诉片段的实际偏移量和资源总大小,格式是bytes x-y/length发送数据,把片段用 TCP 发给客户端
多个范围
MIME 类型
multipart/byteranges,表示报文的 body 是由多段字节序列组成的参数
boundary给出段之间的分隔标记
多段数据的格式,如下:

每个分段必须以
--boundary开始之后用
Content-Type和Content-Range标记这段数据的类型和所在范围最后用一个
--boundary--表示所有的分段结束
这时响应报文的 body 里的多个部分会用 boundary 字符串 00000000001 分隔。
Last updated