HTTP协议传输大文件及断点续传的方式

HTTP传输大文件及断点续传的方式

1. 数据压缩

通常浏览器在发送请求时都会带着 “Accept-Encoding” 头字段,里面是浏览器支持的压缩格式列表,例如 gzip、deflate、br 等,这样服务器就可以从中选择一种压缩算法,放进 “Content-Encoding” 响应头里用来标识这次传输使用的压缩算法,再把原数据压缩后发给浏览器。

优缺点:

数据压缩在处理文本的时候效果还是很好的,但是图片、音频视频等多媒体数据本身就已经是高度压缩的,再用压缩处理也不会变小,此种方式失效。

2. 分块传输

压缩是把大文件整体变小,但是如果大文件整体不能变小,那就把它“拆开”,分解成多个小块,把这些小块分批发给浏览器,浏览器收到后再组装复原。

这样浏览器和服务器都不用在内存里保存文件的全部,每次只收发一小部分,网络也不会被大文件长时间占用,内存、带宽等资源也就节省下来了。

在响应报文里用头字段 “Transfer-Encoding: chunked” 表示报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)分批发送。

注意:“Transfer-Encoding: chunked” 和 “Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。

分块传输的编码规则:

  1. 每个分块含有两个部分,长度头数据块
  2. 长度头是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示某一块数据的长度
  3. 数据块紧跟在长度头后,最后也用 CRLF 结尾
  4. 最后用一个长度为 0 的块表示结束,如下图:
image-20210811113708484

浏览器在收到分块传输的数据后会自动重新组装出内容。

3. 范围请求及断点续传

分块传输可以解决大文件传输的问题,但是有这么一种情况,看电影的过程中快进到某一段,也就是获取大文件中的某一段数据,分块传输并没有这个功能,这就需要使用范围请求

客户端在请求头里使用 ”Range: bytes=左范围-右范围“ 来表示只获取文件的一部分,但是范围请求不是 Web 服务器必备的功能,可以实现也可以不实现,所以服务器必须在响应头里使用字段 “Accept-Ranges: bytes” 明确告知客户端:“支持范围请求”(客户端发送HEAD请求查询)。

如果服务器不支持范围请求,那么服务器可以发送 “Accept-Ranges: none”,或者干脆不发送 “Accept-Ranges” 字段,这样客户端就认为服务器没有实现范围请求功能,只能收发整块文件。

服务器收到 Range 字段后,需要做四件事:

  1. 检查范围是否合法,如果范围越界,服务器就会返回状态码416,意思是“你的范围请求有误,我无法处理,请再检查一下”。
  2. 如果范围正确,服务器就可以根据 Range 头计算偏移量,读取文件的片段了,返回状态码 “206 Partial Content” ,和 200 的意思差不多,但表示 body 只是原数据的一部分。
  3. 服务器要添加一个响应头字段 Content-Range: bytes 左范围 - 右范围 / 资源的总大小,表示将要返回指定范围内的实体内容。
  4. 服务器向客户端发送数据。

有了范围请求之后,HTTP 处理大文件就更加轻松了,看视频时可以根据时间点计算出文件的 Range,不用下载整个文件,直接精确获取片段所在的数据内容。

多段下载、断点续传的应用:

  1. 客户端先发 HEAD,看服务器是否支持范围请求,同时获取文件的大小

  2. 多段下载:开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发请求传输数据

  3. 断点续传:下载意外中断,不必重头再来一遍,只要根据上次的下载记录,用 Range 请求剩下的那一部分就可以了

4. 多段请求

HTTP协议还支持在 Range 头里使用多个“x-y”,一次性获取多个片段数据,如: ”Range: bytes=0-9, 20-29“

这就需要服务端传递一种特殊的 MIME 类型:“multipart/byteranges”,表示报文的 body 是由多段字节序列组成的,并且还要用一个参数 “boundary=xxx” 给出段之间的分隔标记,如下图的响应内容:

image-20210811120802027

每一个分段必须以 “- -boundary” 开始,之后要用 “Content-Type” 和 “Content-Range” 标记这段数据的类型和所在范围,全部分段数据发送之后,最后用一个 “- -boundary- -” 表示所有的分段结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nice2cu_Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值