Http 数据压缩 分块传输 范围请求
作者:互联网
1.首先来看数据压缩
Http传输数据时,会对数据进行压缩,因为有些数据大的有几 G、几十 G 都有可能。
通常浏览器发送请求时会带着“Accept-Econding”头字段,面是浏览器支持的压缩格式列表,例如 gzip、deflate、br 等,这样服务器就可以从中选择一种压缩算法,放进“Content-Encoding”响应头里,再把原数据压缩后发给浏览器。
2.再来看分块传输
分块就是把数据分成一块一块的再发送出去,浏览器收到后再组装起来,这种“化整为零”的思路在 HTTP 协议里就是“chunked”分块传输编码,在响应报文里用头字段“Transfer-Encoding: chunked”来表示,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。
分块传输也可以用于“流式数据”,例如由数据库动态生成的表单页面,这种情况下 body 数据的长度是未知的,无法在头字段“Content-Length”里给出确切的长度,所以也只能用 chunked 方式分块发送。
“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked),这一点你一定要记住。
下面我们来看一下分块传输的编码规则,其实也很简单,同样采用了明文的方式,很类似响应头。
1.每个分块包含两个部分,长度头和数据块;
2.长度头是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示长度;
3.数据块紧跟在长度头后,最后也用 CRLF 结尾,但数据不包含 CRLF;
4.最后用一个长度为 0 的块表示结束,即“0\r\n\r\n”。
3.范围请求
有了分块传输编码,服务器就可以轻松地收发大文件了,但对于上 G 的超大文件,还有一些问题需要考虑。
比如,你在看当下正热播的某穿越剧,想跳过片头,直接看正片,或者有段剧情很无聊,想拖动进度条快进几分钟,这实际上是想获取一个大文件其中的片段数据,而分块传输并没有这个能力。
范围请求”(range requests)的概念,允许客户端在请求头里使用专用字段来表示只获取文件的一部分
服务器会发送专用字段Accept-Ranges: bytes”明确告知客户端:“我是支持范围请求的”,范围请求不是 Web 服务器必备的功能,可以实现也可以不实现。
如果不支持的话该怎么办呢?服务器可以发送“Accept-Ranges: none”,或者干脆不发送“Accept-Ranges”字段,这样客户端就认为服务器没有实现范围请求功能,只能老老实实地收发整块文件了。
客户端会发送Range请求字段,格式是“bytes=x-y”,其中x和Y是以字节为单位的数据范围
Range 的格式也很灵活,起点 x 和终点 y 可以省略,能够很方便地表示正数或者倒数的范围。
假设文件是 100 个字节,那么:“0-”表示从文档起点到文档终点,相当于“0-99”,即整个文件;
“10-”是从第 10 个字节开始到文档末尾,相当于“10-99”;
“-1”是文档的最后一个字节,相当于“99-99”;
“-10”是从文档末尾倒数 10 个字节,相当于“90-99”。
例如客户端请求
GET /16-2 HTTP/1.1
Host: www.chrono.com
Range: bytes=0-31
服务端响应
HTTP/1.1 206 Partial Content
Content-Length: 32
Accept-Ranges: bytes
Content-Range: bytes 0-31/96
服务端收到Range字段后,要做4件事
1.检查范围是否合法
2.范围合法的话,计算偏移量,读取文件的片段,返回状态码“206 Partial Content”,和 200 的意思差不多,但表示 body 只是原数据的一部分。
3.添加响应头字段 Content-Range,告诉片段的实际偏移量和资源的总大小
4.发送数据
范围请求还可以请求获得多个片段
例如;请求多个片段
GET /16-2 HTTP/1.1
Host: www.chrono.com
Range: bytes=0-9, 20-29
会得到服务器响应:
“multipart/byteranges”,表示报文的 body 是由多段字节序列组成的,并且还要用一个参数“boundary=xxx”给出段之间的分隔标记。
每一个分段必须以“- -boundary”开始(前面加两个“-”),之后要用“Content-Type”和“Content-Range”标记这段数据的类型和所在范围,然后就像普通的响应头一样以回车换行结束,再加上分段数据,最后用一个“- -boundary- -”(前后各有两个“-”)表示所有的分段结束。
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges;
boundary=00000000001
Content-Length: 189
Connection: keep-alive
Accept-Ranges: bytes
--00000000001
Content-Type: text/plain
Content-Range: bytes 0-9/96
// this is
--00000000001
Content-Type: text/plain
Content-Range: bytes 20-29/96
ext json d
--00000000001--
如果大家想学习更详细的http知识,推荐到极客时间专栏
都别欺负我胖虎 发布了67 篇原创文章 · 获赞 25 · 访问量 4万+ 私信 关注
标签:Http,请求,分块,bytes,Accept,Content,Range,数据压缩 来源: https://blog.csdn.net/a66666_/article/details/104096103