透视 HTTP 协议
罗剑锋(Chrono)
前奇虎 360 技术专家,Nginx/OpenResty 开源项目贡献者
63943 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
开篇词 (1讲)
透视 HTTP 协议
15
15
1.0x
00:00/00:00
登录|注册

16 | 把大象装进冰箱:HTTP传输大文件的方法

对被gzip的文件执行范围请求的影响
数据里含有回车换行的影响
分段后再分块
压缩后再分块传输
用boundary分隔不同片段
multipart/byteranges
支持视频拖拽和断点续传
Content-Range响应头
Range请求头
Accept-Ranges: bytes
适用于流式数据
Transfer-Encoding: chunked
分块传输编码
适用于文本文件
压缩率提升网速
压缩算法选择
传输多种类型数据
课下作业
方法混合使用
多段数据
范围请求
分块传输
数据压缩
HTTP报文body
HTTP大文件传输

该思维导图由 AI 生成,仅供参考

上次我们谈到了 HTTP 报文里的 body,知道了 HTTP 可以传输很多种类的数据,不仅是文本,也能传输图片、音频和视频。
早期互联网上传输的基本上都是只有几 K 大小的文本和小图片,现在的情况则大有不同。网页里包含的信息实在是太多了,随随便便一个主页 HTML 就有可能上百 K,高质量的图片都以 M 论,更不要说那些电影、电视剧了,几 G、几十 G 都有可能。
相比之下,100M 的光纤固网或者 4G 移动网络在这些大文件的压力下都变成了“小水管”,无论是上传还是下载,都会把网络传输链路挤的“满满当当”。
所以,如何在有限的带宽下高效快捷地传输这些大文件就成了一个重要的课题。这就好比是已经打开了冰箱门(建立连接),该怎么把大象(文件)塞进去再关上门(完成传输)呢?
今天我们就一起看看 HTTP 协议里有哪些手段能解决这个问题。

数据压缩

还记得上一讲中说到的“数据类型与编码”吗?如果你还有印象的话,肯定能够想到一个最基本的解决方案,那就是“数据压缩”,把大象变成小猪佩奇,再放进冰箱。
通常浏览器在发送请求时都会带着“Accept-Encoding”头字段,里面是浏览器支持的压缩格式列表,例如 gzip、deflate、br 等,这样服务器就可以从中选择一种压缩算法,放进“Content-Encoding”响应头里,再把原数据压缩后发给浏览器。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

HTTP大文件传输涉及数据压缩和分块传输两种解决方案。数据压缩通过压缩算法将文件大小减小,提高传输速度,但对于多媒体数据效果有限。分块传输则将大文件分解成小块,逐个发送至浏览器,减少内存和带宽资源占用。HTTP协议中的chunked分块传输编码通过将数据分成多个块逐个发送,实现了流式数据传输。文章还介绍了范围请求的概念,允许客户端在请求头里使用专用字段来表示只获取文件的一部分,实现视频拖拽或者断点续传。此外,文章还探讨了多段数据的传输方式,通过使用特殊的MIME类型和分隔标记来一次性获取多个片段数据。总的来说,文章介绍了HTTP传输大文件的基本方法、分块传输、范围请求和多段数据的应用,为读者提供了全面的技术知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《透视 HTTP 协议》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(93)

  • 最新
  • 精选
  • Aaaaaaaaaaayou
    老师,有个问题:http交给tcp进行传输的时候本来就会分块,那http分块的意义是什么呢?

    作者回复: 在http层是看不到tcp的,它不知道下层协议是否会分块,下层是否分块对它来说没有意义,不关心。 在http里一个报文必须是完整交付,在处理大文件的时候就很不方便,所以就要分块,在http层面方便处理。 chunked主要是在http的层次来解决问题。

    2019-07-03
    15
    84
  • chengzise
    1. 分块传输中数据里含有回车换行(\r\n)不影响分块处理,因为分块前有数据长度说明 2. 范围是应用于压缩后的文件

    作者回复: 1正确。 2需要分情况,看原文件是什么形式。如果原来的文件是gzip的,那就正确。如果原文件是文本,而是在传输过程中被压缩,那么就应用于压缩前的数据。 总之,range是针对原文件的。

    2019-07-03
    3
    76
  • 赵健
    “Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked),这一点你一定要记住。老师请问下,为啥分块意味着长度未知,后面不是提到块里面有个长度头嘛?而且单个块应该是一次http传输的内容,既然块里有长度头,那这次传输的内容长度也就能算出来,这次http的Content-Length 也就知道啊!是我理解错了吗

    作者回复: 举个例子,从GitHub上下载源码包,GitHub要实时压缩实时发送,而不是一下子压缩好再发送,这样body的长度一开始就是未知的。 所以就要用分块编码,压缩一部分,就发一部分,这部分的长度是已知的,但总长度只有压缩完才能知道。 chunked编码用在“流式”收发数据的时候,通常数据是即时生成的,也就是动态数据。

    2019-07-04
    4
    58
  • 秋水共长天一色🌄
    老师,我有些问题需要问问您。 1.比如我在视频网上看电影,我们经常能看到进度条里面有一条灰色的缓存进度,我是否能理解成这个进度就是分块传输的一个进度显示吗? 2.刚刚我有看到评论说过一个问题就是分块传输的时候是由一个请求和一个响应完成的,如果我们在抓一个需要10分钟才能完成分块传输的请求时,我是不是就会看到这个请求在这10分钟内都是一个正在响应的状态吗? 3.为什么我们在对一些视频网站看视频抓包的时候却无法捕抓到这个请求呢? 4.如果我们在看完视频后在浏览器缓存里发现一些片段式的视频文件,能否就说明这个是用分块传输呢? 5.如果我们在看视频拖动进度条到10分30秒,到最后视频会从10分20秒开始播放,能否说明10分30秒的这个分块的头是在10分20秒呢? 6.请问多段数据能理解成一次性获取分块传输里多个连续的分块的数据的意思吗? 还有就是非常感谢老师把这些知识点讲的那么细,我近期多个面试里都有被问到相关的知识,多亏老师的讲解我才能顺利应付,谢谢老师!!!

    作者回复: 1.网络视频不一定用的就是http协议,也可能是其他的专用协议,所以不能简单地判断就是分块传输。如果是http协议,对于大文件通常都是range请求,也不一定用chunk分块。 2.是的,这是由http的请求-应答工作模式决定的。不管是不是chunk,只要响应没有结束,这个来回就不会完成。 3.也可能用的是其他协议。 4.应该是range的分段,不是chunk,chunk只是在传输过程中分块,最后到客户端会是一个完整的文件。 5.视频文件的分段计算比较复杂,课程里面只是作为简单的示例,实际情况不一定就是这么简单。 6.分段的range和分块的chunk是两个完全无关的概念,不要弄混了。chunk是传输时分成小块逐个发送,range是取大文件中间的一部分。 7.不客气,后面的https、http/2也继续努力吧。

    2019-07-29
    2
    54
  • 小桶
    分块传输,客户端只需要发一次请求,还是发多次请求呢?使用分块传输时,客户端与服务器是怎样工作的呢

    作者回复: http传输永远是一个请求一个响应的工作模式,只是响应是chunked分块,body数据不是一次性发过来的,而是分批分块发送,但仍然是在一个报文里。 客户端发送请求后等待响应,服务器组织数据,分块发送,最后一个分块是结束标志。客户端依次接收分块,收到结束标志后就把数据拼成完整的报文。

    2019-07-20
    12
    44
  • 对于问题2,range是针对原文的还是压缩后的,可以想象一下看视频的时候,我们拖拽进度条请求的range范围是针对原视频长度的,如果针对压缩后的,那么我们实际拖拽的范围和响应的数据范围就不一致了

    作者回复: 说的很好。

    2019-07-04
    23
  • darren
    不分块:http把客户端需要的东西整个交给tcp,由tcp切块后发送给客户端,客户端接受后在tcp层组装完整发给浏览器使用。 分块:http把客户端需要的东西切分成1、2、3到n块,然后将1块发给tcp,tcp将块1再次切分后发给客户端,客户端接受后在tcp组装成块1发给http层。然后服务器与客户端用同样的方式发送块2、块3到块n。客户端的http在接收完所有块后组装成一个完整的响应。整个过程使用同一个tcp连接,块1到块n如上是挨个发送的。如果是http2,则基于多路复用技术块1到块n可以同时发送。所以分块抓包http只能抓到一个包,如果抓tcp的包,分不分块,都会抓到很多包。 分段:分段就是对某个资源的一部分进行请求(类似于把一个大文件切分成很多小文件,类似压缩中的分卷功能,然后客户端只对这些小文件中的一部分进行请求) 分段是对需要哪些资源进行一种说明,分块是一种传输机制,完全不同的两个东西,只是名字比较像。 请老师指教理解不正确的地方,另外想问一下老师分块的时候每个块都会复制一次响应头吗,还是只有块1带有请求头。

    作者回复: 总结的非常好,很清晰。 chunk数据实际上是一个很大的请求,只有一个header,只是逐个地发出去,而不是一次性发。 可以在实验环境里抓包看看。

    2021-04-07
    17
  • -W.LI-
    老师好!在带宽固定的情况下,范围请求没发提高下载速度。如果服务器对客户端每个累链接限速的情况下,可通过多线程并发下载,提高下载速度是么?还有几个问题 分块传输:顺序传一次一小块 范围请求:支持跳跃式传输,还可以并发获取不同的range最后合并。 多段数据:一次请求多个范围,范围可以不连续是么?如果必须联系的话和请求一个大范围没差别了。 这几个拒的例子都是服务端这么返回的。 客户端上传的时候怎么使用呢?老师后面会讲么。 只读到了这么点,希望老师补充下每个的作用,和解决的问题,谢谢老师。

    作者回复: 1,是的,通过多线程并发下载,提高下载速度。 2,范围可以不连续,例子里就是这样。 3,客户端上传的时候也可以用chunked、gzip,但不能用range。 注意这些字段的类型,只要是实体字段,那就在请求响应里都可以用。

    2019-07-03
    15
  • 一只鱼
    针对课下作业2: 情况一:如果服务器上只有 gzip 之后的文件,没有原文件,那范围请求针对的就是 gizp 之后的文件; 情况二:如果服务器上有原文件(未压缩),只是在传输过程中被 gizp , 那范围请求针对的就是未压缩的原文件。 这里拓展一下,假如在服务器和客户端之间有一个 cdn , 那么 cdn 缓存的是文件的某个范围吗?cdn 会根据请求头判断缓存里面有没有这个范围的结果,如果有就直接返回,并没有再根据bytes进行计算?

    作者回复: 说的对。 第二个问题,如果按标准http协议的做法就是只缓存一个范围,但这样的效果不会很好,因为缓存的这部分被重复利用的机会很小。 更好的方法是cdn返回给客户端的同时,把整个文件都从源站取下来,之后就可以自己计算范围给客户端,不用再从源站取了。

    2020-04-10
    11
  • wheat7
    chunk的核心问题并不是所谓把大象装进冰箱,是为了解决应用层在没有content-length的时候知道数据在哪里结束,chunk和普通传输方式都是在一个http报文里传输的,只是在body里相当于又加了一层协议或者是编码,数据无论如何是在一头大象里,在一个http报文中传输,大的数据传输使用chunk和不使用传输方式并没有什么区别。

    作者回复: 说的很有道理。 不过两者还是有区别的,chunked主要用于流式数据,一开始不能知道准确的大小。

    2019-07-12
    6
    7
收起评论
显示
设置
留言
93
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部