ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Http 数据压缩 分块传输 范围请求

2020-01-28 16:37:11  阅读:496  来源: 互联网

标签:Http 请求 分块 bytes Accept Content Range 数据压缩


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有