透视HTTP协议
罗剑锋(Chrono)
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
6077 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词|To Be a HTTP Hero
免费
破冰篇 (7讲)
01 | 时势与英雄:HTTP的前世今生
02 | HTTP是什么?HTTP又不是什么?
03 | HTTP世界全览(上):与HTTP相关的各种概念
04 | HTTP世界全览(下):与HTTP相关的各种协议
05 | 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?
06 | 域名里有哪些门道?
07 | 自己动手,搭建HTTP实验环境
基础篇 (7讲)
08 | 键入网址再按下回车,后面究竟发生了什么?
09 | HTTP报文是什么样子的?
10 | 应该如何理解请求方法?
11 | 你能写出正确的网址吗?
12 | 响应状态码该怎么用?
13 | HTTP有哪些特点?
14 | HTTP有哪些优点?又有哪些缺点?
进阶篇 (8讲)
15 | 海纳百川:HTTP的实体数据
16 | 把大象装进冰箱:HTTP传输大文件的方法
17 | 排队也要讲效率:HTTP的连接管理
18 | 四通八达:HTTP的重定向和跳转
19 | 让我知道你是谁:HTTP的Cookie机制
20 | 生鲜速递:HTTP的缓存控制
21 | 良心中间商:HTTP的代理服务
22 | 冷链周转:HTTP的缓存代理
安全篇 (7讲)
23 | HTTPS是什么?SSL/TLS又是什么?
24 | 固若金汤的根本(上):对称加密与非对称加密
25 | 固若金汤的根本(下):数字签名与证书
26 | 信任始于握手:TLS1.2连接过程解析
27 | 更好更快的握手:TLS1.3特性解析
28 | 连接太慢该怎么办:HTTPS的优化
29 | 我应该迁移到HTTPS吗?
飞翔篇 (4讲)
30 | 时代之风(上):HTTP/2特性概览
31 | 时代之风(下):HTTP/2内核剖析
32 | 未来之路:HTTP/3展望
33 | 我应该迁移到HTTP/2吗?
探索篇 (5讲)
34 | Nginx:高性能的Web服务器
35 | OpenResty:更灵活的Web服务器
36 | WAF:保护我们的网络服务
37 | CDN:加速我们的网络服务
38 | WebSocket:沙盒里的TCP
总结篇 (2讲)
39 | HTTP性能优化面面观(上)
40 | HTTP性能优化面面观(下)
答疑篇 (2讲)
41 | Linux/Mac实验环境搭建与URI查询参数
42 | DHE/ECDHE算法的原理
结束语 (1讲)
结束语 | 做兴趣使然的Hero
透视HTTP协议
登录|注册

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

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

数据压缩

还记得上一讲中说到的“数据类型与编码”吗?如果你还有印象的话,肯定能够想到一个最基本的解决方案,那就是“数据压缩”,把大象变成小猪佩奇,再放进冰箱。
通常浏览器在发送请求时都会带着“Accept-Encoding”头字段,里面是浏览器支持的压缩格式列表,例如 gzip、deflate、br 等,这样服务器就可以从中选择一种压缩算法,放进“Content-Encoding”响应头里,再把原数据压缩后发给浏览器。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《透视HTTP协议》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(41)

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

    作者回复: 在http层是看不到tcp的,它不知道下层协议是否会分块,下层是否分块对它来说没有意义,不关心。

    在http里一个报文必须是完整交付,在处理大文件的时候就很不方便,所以就要分块,在http层面方便处理。

    chunked主要是在http的层次来解决问题。

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

    作者回复: 举个例子,从GitHub上下载源码包,GitHub要实时压缩实时发送,而不是一下子压缩好再发送,这样body的长度一开始就是未知的。

    所以就要用分块编码,压缩一部分,就发一部分,这部分的长度是已知的,但总长度只有压缩完才能知道。

    chunked编码用在“流式”收发数据的时候,通常数据是即时生成的,也就是动态数据。

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

    作者回复: http传输永远是一个请求一个响应的工作模式,只是响应是chunked分块,body数据不是一次性发过来的,而是分批分块发送,但仍然是在一个报文里。

    客户端发送请求后等待响应,服务器组织数据,分块发送,最后一个分块是结束标志。客户端依次接收分块,收到结束标志后就把数据拼成完整的报文。

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

    作者回复: 1正确。

    2需要分情况,看原文件是什么形式。如果原来的文件是gzip的,那就正确。如果原文件是文本,而是在传输过程中被压缩,那么就应用于压缩前的数据。

    总之,range是针对原文件的。

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

    作者回复: 1,是的,通过多线程并发下载,提高下载速度。

    2,范围可以不连续,例子里就是这样。

    3,客户端上传的时候也可以用chunked、gzip,但不能用range。

    注意这些字段的类型,只要是实体字段,那就在请求响应里都可以用。

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

    作者回复: 说的很好。

    2019-07-04
    5
  • 彧豪
    老师我有几个疑问:
    1. 比如总共是1314的数据, 响应头会这么写`Content-Range: bytes 0-1313/1314`, 为何会少1?
    2. 浏览器如何开N个线程下载数据?多个ajax请求?

    作者回复: 1,计算范围从0开始计数,用的是C语言惯例。

    2,浏览器的技术不是很清楚,抱歉了。

    2019-07-21
    2
  • 响雨
    响应报文返回的数据太大,所以采用了chunk分块传输的话,那响应报文在传输完成前是什么样子,响应行和头过来了,响应体还在流式传递,那响应体内的数据该怎么展示?

    作者回复: 就是按照格式分成一些片段,逐块发送,浏览器收到后去掉分隔符,再拼成原来的样子。

    2019-07-05
    2
  • 白了少年头
    1.数据里有回车换行,会影响分块的处理
    2.范围应用于压缩后文件
    不知道对不对,辛苦老师解答一下,谢谢!

    作者回复: 1不对,前面已经有同学回答了,因为分块包含了长度,所以回车换行不影响。

    2需要分情况,看原文件是什么形式。如果原来的文件是gzip的,那就正确。如果原文件是文本,而是在传输过程中被压缩,那么就应用于压缩前的数据。

    总之,range是针对原文件的。

    2019-07-03
    2
  • Flourishing
    老师,请问一下:“分块传输也可以用于“流式数据””。该怎么理解这个“流式数据”这句话呢?

    作者回复: 流式数据就是stream,虽然还是用一个个的chunk发过来的,但从更高层次上看,它像是从源头持续不断地、慢慢地“流”过来的,而不是一次性、一整块发过来的。

    可以对比一下tcp和udp,tcp是流式数据,而udp是一个个的数据包。

    2019-12-04
    1
  • ly
    有几个小疑问:
    分块传输:
    对于一个500Mb的数据,客户端应该是发送N次http请求,每次http请求只传输其中一部分,每次都是采用了分块传输的body格式,那么每次都会重新建立TCP连接吗(三次握手)?

    另外文章提到分块传输中的“流式数据”,这个流式数据怎么理解呢?

    对于多段数据:
    服务端在响应body里面的每一段都会指定Content-Type和Content-Range,总感觉其中的Content-Type字段是多余的,难道body里面的不同分段,Content-Type可能不一样?

    作者回复:
    1.请参考一下讲长连接的那一讲,现在的http请求应该都是使用的长连接,不会每次都重新建立连接,否则效率太低。

    2.流式数据就是分块发送,像tcp那样一块一块地发过来,而不是像普通http那样一次完整地全发过来。

    3.多段数据可以是mulitpart,每段数据是有可能不同的,比如发出一个请求,服务器返回了一个txt和json,所以要这么做。当然这种情况比较少见,但协议就必须要考虑到这种情况。

    2019-08-18
    1
  • 业余草
    数据的分段传输。把断点续传与断点下载搞懂,你就可以破解百度网盘的非会员限速功能了!

    作者回复: 服务器掌控数据,有很多办法可以限流限速,不是简单的客户端就能控制的。

    2019-07-10
    1
  • 苦行僧
    老师 我们的业务就是视频处理 经常涉及的就是视频下载本地处理 使用的是ftp协议 如果使用http会更快?

    作者回复: 这个需要实际测试,http的优势是灵活,相关的工具多,传输效率上都是依赖于底层的tcp,应该差不多。

    2019-07-04
    1
  • Geek_54edc1
    1、因为分块数据是明文传输,如果数据里有\r\n,是会影响分块处理的
    2、个人感觉应该是应用于原文件

    作者回复: 1不对,因为chunked格式里已经有长度了。

    2正确。

    看来有不少同学对第二个问题比较迷惑,我再说具体一点。

    比如说,有一个1M的纯文本,range请求其中的500K,然后服务器编码为gzip(Content-Encoding: gzip),压缩成200k,浏览器收到后解压缩,就得到了这部分的500k数据。

    2019-07-03
    1
  • 虢国技匠
    讲的真好,简单清晰,赞

    作者回复: thanks。

    2019-07-03
    1
  • 一粟
    迅雷下载或者在线视频播放器是不是在使用分块或者任意请求功能?

    作者回复: 只要是用http传输,就会用range,但他们也有可能用自己的协议而不是http,比如rmtp。

    2019-07-03
    1
  • 啦啦啦
    打卡打卡收获颇多
    2019-07-03
    1
  • Geek_362669
    chunk 分块长度有大小限制吗?有的话最大是多少

    作者回复: 标准规范里没有限制,但不宜太大,过大就失去了分块的意义。

    2019-11-01
  • hz
    http传输永远是一个请求一个响应的工作模式.
    老师,分块传输是每一个块相当于HTTP的“一个请求一个响应吗”
    客户端收到分块数据然后拼接成一个完整的HTTP报文,这是在HTTP层做的,还是在TCP层做的呢。

    作者回复: http协议当然是在http层次做的了,看不到下层的tcp。

    虽然是chunked,但这仍然是一个响应,只是body部分被分成了多个部分。

    注意,我们必须要很好地理解网络协议栈,虽然在下层tcp/ip可能也会分成多个块,但在它们之上是看不到的,http看到的是它自己的分块,而不是tcp的分块。

    2019-10-27
收起评论
41
返回
顶部