12 HTTP传输大文件
-
总结
1、压缩
HTML
等文本文件是传输大文件最基本的方法2、分块传输 可以流式收发数据,节约内存和带宽,使用响应头字段
Transfer-Encoding: chunked
来表示,分块的格式是 16 进制长度头 + 数据块;3、范围请求 可以只获取部分数据,即
分块请求
,实现 视频拖拽或者断点续传,使用请求头字段Range
和响应头字段Content-Range
,响应状态码必须是 206;4、也可以一次 请求多个范围,这时候响应报文的数据类型是
multipart/byteranges
,body
里的多个部分会用boundary
字符串分隔
1/4、数据压缩
-
优点
如果压缩率能有 50%,也就是说 100K 的数据能够压缩成 50K 的大小,那么就相当于在带宽不变的情况下网速提升了一倍,加速的效果是非常明显的
-
缺点
gzip
等压缩算法通常 只对文本文件有较好的压缩率,而图片、音频视频等多媒体数据本身就已经是高度压缩的,再用gzip
处理也不会变小,所以它就失效了
2/4、分块传输 chunked
-
标志:响应头
Transfer-Encoding: chunked
,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk
)逐个发送 -
分块传输的编码规则:
1、每个分块包含两个部分,长度头 和 数据块;
2、长度头是以
CRLF
(回车换行,即\r\n
)结尾的一行明文,用 16 进制数字表示长度3、数据块紧跟在长度头后,最后也用
CRLF
结尾,但数据不包含CRLF
4、最后用一个长度为 0 的块表示结束,即
0\r\n\r\n
范围请求
客户端在 请求头 里使用 Range:bytes=x-y
来表示只获取文件的一部分;
- 注意:范围请求不是 Web 服务器必备的功能,服务器在 响应头 中需要通过
Accept-Ranges: bytes
来声明是支持范围请求的
请求头 中的字段 Range
支持很多种格式写法:
-
x 和 y 是以 字节 为单位的数据范围,起点 x 和终点 y 可以省略,能够很方便地表示正数或者倒数的范围
1、
0-
表示从 文档起点到文档终点,相当于0-99
,即整个文件2、
10-
是从第 10 个字节开始到文档末尾,相当于10-99
3、
-1
是文档的最后一个字节,相当于99-99
4、
-10
是从文档末尾倒数 10 个字节,相当于90-99
服务器收到请求头中的 Range
字段,需要进行几步操作:
1、检查范围是否合法 - 范围有误则返回状态码 - 416
2、根据 Range
头计算偏移量,读取文件的片段 - 206 Partial Content
,表示 body 只是原数据的一部分
3、服务器要添加一个 响应头 字段 Content-Range
,表示片段的实际偏移量和资源的总大小,格式是 bytes x-y/length
(与 Range
头区别在没有 =
,范围后多了总长度)
4、发送数据 - 把片段用 TCP
发给客户端
多段数据
请求头 Range
头里使用多个 x-y
,一次性获取多个片段数据
响应头形式如下,可以结合图片理解:
- 用一个参数
boundary=xxx
给出段之间的分隔标记
1、每一个分段必须以 --boundary
开始
2、之后要用 Content-Type:multipart/byteranges
和 Content-Range
标记这段数据的类型是多段字节序列组成和所在范围
3、以回车换行结束,再加上分段数据
4、最后用一个 --boundary--
表示所有的分段结束