其他分享
首页 > 其他分享> > Http 数据压缩 分块传输 范围请求

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