美文网首页
HTTP传输大文件

HTTP传输大文件

作者: dashingqi | 来源:发表于2022-05-29 10:19 被阅读0次
    Android_Banner.jpg

    我们知道HTTP报文中的body不仅可以传输文本还可以传输图片、视频以及音频;

    随着互联网的发展,现在随便一个HTML文件就有几百KB,如果是高质量的图片或者视频那都要M或者GB了;

    我们的带宽都是固定在这些大文件面前就显的微不足道;

    接下来我们就看看在HTTP协议加持下是如何在固定宽带的情况下传输这些超大文件的

    数据压缩

    在【HTTP Body】一文中我们介绍【数据类型与编码】中就有关于针对body报文的压缩

    我们在请求头字段中使用【Accept-Encoding: gzip】告知服务器我们能接受gzip压缩类型的数据;

    同时在响应头中使用【Content-Encoding:gzip】和body中把数据传递给客户端;

    【数据压缩】就是把我们巨大的数据量【成年的猪猪】---> 【幼年的小猪羔子】然后在回传给客户端;

    不过gzip这种压缩针对文本压缩还是很有效果的;对于图片或者音频来说,本身也是经过处理的了使用gzip的收益不大;

    不过在传输文本的时候服务器还是会使用gzip作为一次【保底】;

    除了压缩数据之外,HTTP还是支持分块传输的;

    分块传输

    分块传输也就是把数据切成很多块,分批传递给客户端客户端收到后在重新组装,思想就是减少每次数据的传输量;

    在HTTP协议头字段中,针对分块传输的表现是使用【Transfer-Encoding:chunked】表示响应报文body中的数据不是一次性全部传递过来的,而是分成很多块逐个发送的;

    分块传输也可以用于【流式数据】;例如数据库动态生成的表单页面;这种情况下body数据的长度是未知,那么头字段中【Content-Length】无法给出确切的长度

    换句话说,在响应报文中【Content-Length】和【Transfer-Encoding:chunked】不能同时出现;一个响应报文长度要么是【已知】的要么是【未知】的;

    分块传输的规则
    • 每个分块包含两个部分。长度头和数据块;

    • 长度头是以CRLF(回车换行,即\r\n)结尾的一行明文,用16进制数字表示长度;

    • 数据块在长度头之后,最后用CRLF结尾,数据块不包含CRLF

    • 最后用一个长度为0的块表示结束,即【0\r\n\r\n】

    HTTP中body的分块传输.png

    范围请求

    使用场景
    • 当我们观看一部电影时,去跳过片头时(拖拽进度条前进),使用到了范围请求;

      这个实际上是获取一个大文件其中的片段数据;我们的分块传输并没有这个能力;

    任何技术的出现都是为了满足用户需求出现的,范围请求就是为了解决上述类似场景的需求;

    HTTP协议允许客户端在请求头里使用专用字段获取文件的一部分;

    范围请求不是WEB服务器必备的功能;服务器可以在响应头字段中使用【Accept-Ranges:bytes】明确告知客户端我是不是支持的

    不支持
    • 不支持:服务器就返回【Accept-Ranges:none】或者就不返回对应的字段;
    支持

    【Range】是HTTP范围请求中请求头的专用字段,格式是【bytes=x-y】x和y是以字节为单位的数据范围;

    范围必须从0计数【0-9】表示前10个字节,【10-19】表示第二个10字节;

    灵活的Range格式

    【0-】表示从数据起点到终点,表示整个文件

    【10-】表示从第10个字节开始到文档结尾;

    【-1】表示最后一个字节;

    【-10】表示文档末尾倒数10个字节;

    服务器收到Range的处理

    • 检查范围的合法性,如果范围越界了,服务器就会返回状态码【416】;

    • 范围正确的话,就根据Range头计算返回数据的片段;此时的状态码为【206 Partial Content】

    • 同时服务器会在响应头字段中添加一个【Content-Range】告诉片段的实际偏移量和资源的总大小

      • 这里在说下,响应头中会返回【Accept-Range】用于告知服务器是否支持范围请求的;

    响应头中的【Content-Range】

    格式是 【bytes x-y/length】与请求头中的Range区别在于没有【=】,范围区间后多了【总长度length】

    应用场景
    • 视频拖拽进度

    • 下载工具里的多段下载,断点续传

    大概思路

    • 发送一个HEAD请求,查看服务器是否支持范围请求,同时能获取到文件的大小

    • 开启线程,线程中发起的网络请求使用Range字段划分出各自负责的下载的片段;

    多段数据

    上文说的范围请求一次只能获取一个数据片段,当在请求头【Range】中使用多个【x-y】就能一次性获取多个片段数据了,也就是【多段数据】

    上述【多段数据】使用情况使用特殊的MIME 【multipart/byteranges】表示响应报文中body是由多段数据组成的;

    同时使用【boundary=xxx】标识出每段之间的分隔标记;

    直接上示意图

    HTTP中的body-多段数据是以图.png

    相关文章

      网友评论

          本文标题:HTTP传输大文件

          本文链接:https://www.haomeiwen.com/subject/nkdgprtx.html