We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在上面我们已经讲过 HTTP 传输数据时,有一个字段是 Accept-Encoding,它代表客户端支持的数据压缩的格式,这样服务器就可以选择其中一种,放到 Content-Encoding 中,再把原来的数据压缩后发送给浏览器。
如果压缩率有50%,那么原来100k 的数据就可以压缩成50k 大小,极大地提升传输效率。
这种压缩方式非常适合文本如(text/html)的压缩,不过并不适合传输图片、音频视频等数据,因为它们本身已经高度压缩了。
除了数据压缩之外,还可以把大文件整体变小,分解成很多个小块,这样就可以把小块分发给浏览器,浏览器收到后复原。
这种方式有个好处,每次只收发一小部分,网络不会被大文件长时间占用,可以节省带宽资源。
这种方法在 HTTP 中叫 chunked 分块传输,在响应报文里用头字段 Transfer-Encoding:chunked 来表示。意思是报文的 body 可以分成多次发送。
chunked
Transfer-Encoding:chunked
分块传输可以用于流式数据,例如数据库动态生成的表单页面,这种情况下 body 数据的长度是未知的,无法在头字段 Content-Length 里给出确切的长度,所以也只能用 chunked 方式分块发送。
“Transfer-Encoding: chunked”和“Content Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。
分块传输就是把大文件分成很多个小块,那么假设我希望获取大文件中特定的片段数据,显然没办法用分块传输做到。
HTTP 协议中,还有一种范围请求可(range requests)的概念,允许客户端在请求头里面使用专用字段来表示只获取文件的一部分。
在做范围请求前,需要 Web 服务器在响应头上使用字段 Accept-Ranges:bytes,明确告知客户端支持范围请求。不支持则可以不传这个字段或者设置为 none
Accept-Ranges:bytes
none
请求头 Range 是 http 范围请求的专用字段,格式是 bytes=x-y,其中 x和 y 是以字节为单位的数据范围。
需要注意 x、y 表示的是偏移量,范围从0计算,比如前10个字节表示为0-9.
其中 x 和 y 是可以省略的,0-表示文档起点到终点,-1表示文档最后一个字节,-10表示从文档末尾倒数10个字节。
服务器收到 Range 字段后,需要做四件事
检查范围是否合法。不合法可以返回416编码。
范围正确,服务器需要根据 Range 头计算偏移量,读取文件的片段,返回206 Partial Content,表示 body 只是数据的一部分
206 Partial Content
服务器需要加上响应头 Content-Range,告诉片段的实际偏移量和资源的总大小,格式则是bytes x-y/length,和请求头的 Range 字段区别是没有=号且范围后多了总长度。
Content-Range
bytes x-y/length
=
最后发送数据了
范围请求的常见应用是视频的拖拽进度和多段下载、断点续传等。
范围请求还支持一次获取多个片段数据,可以在 Range 中使用多个x-y。
x-y
这种情况需要一种特殊的 MIME 类型:multipart/byteranges,表示报文的 body 是由多段字节序列组成的,并且还要给一个参数 boundary=xxx给出段之间的分割标记。
multipart/byteranges
boundary=xxx
压缩 HTML 等文件是传输大文件的基本方法
分块传输可以流式收发数据,节省内存和带宽。使用响应头 Transfer-Encoding:chunked
范围请求可以只获取部分数据。主要应用于断点续传和视频拖拽等。使用请求头字段 Range 和响应头字段 Content-Range。相关响应状态码416和206
Range
也可以一次性请求多个范围,此时响应报文的Content-type 是multipart/byteranges,body 部分多个部分会用 boundary 字符串分隔。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
传输大文件的方法
数据压缩
在上面我们已经讲过 HTTP 传输数据时,有一个字段是 Accept-Encoding,它代表客户端支持的数据压缩的格式,这样服务器就可以选择其中一种,放到 Content-Encoding 中,再把原来的数据压缩后发送给浏览器。
如果压缩率有50%,那么原来100k 的数据就可以压缩成50k 大小,极大地提升传输效率。
这种压缩方式非常适合文本如(text/html)的压缩,不过并不适合传输图片、音频视频等数据,因为它们本身已经高度压缩了。
分块运输
除了数据压缩之外,还可以把大文件整体变小,分解成很多个小块,这样就可以把小块分发给浏览器,浏览器收到后复原。
这种方式有个好处,每次只收发一小部分,网络不会被大文件长时间占用,可以节省带宽资源。
这种方法在 HTTP 中叫
chunked
分块传输,在响应报文里用头字段Transfer-Encoding:chunked
来表示。意思是报文的 body 可以分成多次发送。分块传输可以用于流式数据,例如数据库动态生成的表单页面,这种情况下 body 数据的长度是未知的,无法在头字段 Content-Length 里给出确切的长度,所以也只能用 chunked 方式分块发送。
“Transfer-Encoding: chunked”和“Content Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。
范围请求
分块传输就是把大文件分成很多个小块,那么假设我希望获取大文件中特定的片段数据,显然没办法用分块传输做到。
HTTP 协议中,还有一种范围请求可(range requests)的概念,允许客户端在请求头里面使用专用字段来表示只获取文件的一部分。
在做范围请求前,需要 Web 服务器在响应头上使用字段
Accept-Ranges:bytes
,明确告知客户端支持范围请求。不支持则可以不传这个字段或者设置为none
请求头 Range 是 http 范围请求的专用字段,格式是 bytes=x-y,其中 x和 y 是以字节为单位的数据范围。
需要注意 x、y 表示的是偏移量,范围从0计算,比如前10个字节表示为0-9.
其中 x 和 y 是可以省略的,0-表示文档起点到终点,-1表示文档最后一个字节,-10表示从文档末尾倒数10个字节。
服务器收到 Range 字段后,需要做四件事
检查范围是否合法。不合法可以返回416编码。
范围正确,服务器需要根据 Range 头计算偏移量,读取文件的片段,返回
206 Partial Content
,表示 body 只是数据的一部分服务器需要加上响应头
Content-Range
,告诉片段的实际偏移量和资源的总大小,格式则是bytes x-y/length
,和请求头的 Range 字段区别是没有=
号且范围后多了总长度。最后发送数据了
范围请求的常见应用是视频的拖拽进度和多段下载、断点续传等。
多段数据
范围请求还支持一次获取多个片段数据,可以在 Range 中使用多个
x-y
。这种情况需要一种特殊的 MIME 类型:
multipart/byteranges
,表示报文的 body 是由多段字节序列组成的,并且还要给一个参数boundary=xxx
给出段之间的分割标记。小结
压缩 HTML 等文件是传输大文件的基本方法
分块传输可以流式收发数据,节省内存和带宽。使用响应头
Transfer-Encoding:chunked
范围请求可以只获取部分数据。主要应用于断点续传和视频拖拽等。使用请求头字段
Range
和响应头字段Content-Range
。相关响应状态码416和206也可以一次性请求多个范围,此时响应报文的Content-type 是multipart/byteranges,body 部分多个部分会用 boundary 字符串分隔。
The text was updated successfully, but these errors were encountered: