HTTP下载中的:Range和Chunked
我们经常通过HTTP协议下载大文件时,常见的有两种情况:
- 知道文件大小,通过请求头Range设定服务器要返回的文件部分。常见的大文件分片下载、音视频的拖动播放都是采用的这种方式实现的。
- 不知道文件大小,可以设定
Transfer-Encoding为Chunked,表示分块编码。常见的实时音视频流都是采用这种方式实现的。
基于Ranges的分片下载与断点续传
HTTP/1.1 200 OK
[请求内容...]
If-Range: "a6a6d2d4f69b23ecf12a6de3daca3a18-4"
Range: bytes=7143424-15741306
[响应内容...]
Accept-Ranges: bytes
Content-Length: 4177094
Content-Range: bytes 4980736-9157829/9157830
ETag: "a6a6d2d4f69b23ecf12a6de3daca3a18-4"
Date: Wed, 09 Feb 2022 06:51:43 GMT
Last-Modified: Wed, 08 Dec 2021 15:40:43 GMT
请求头Range指定下载内容,如果是从开头开始,可以指定 Range: bytes=0- ,如果只想要最后的500bytes的数据,可以指定 Range: bytes=-500 。如果用户输入的Range范围有误,服务器会返回416-Range Not Satisfiable状态码。
请求头If-Range只在Range请求头存在时起作用(可选的),If-Range用来判断资源是否发生变化。在请求过程中,If-Range 使用 ETag 或者 Last-Modified 两个参数任意一个,原样填入即可。如果两次请求过程中,资源没有发生变化,会继续返回206-Partial Content状态码;否则,则会返回200状态码,表示文件已经改变,需要重头下载。
响应头Accept-Ranges: bytes 标示自身支持范围请求(partial requests)
响应头Content-Length: 4177094 是用来表示发送给接收方消息主体的大小,注意 Content-Length 是当前响应的内容实体长度,并不是整个资源的完整长度。
响应头Content-Range显示一个数据片段在整个文件中的位置。首先展示的它的单位bytes,然后是当前传递的资源的范围和整体的长度。
If-Range Range Accept-Ranges Content-Length Content-Range ETag Date Last-Modified