HTTP 范围请求
HTTP Range
请求要求服务器仅将 HTTP 消息的一部分发送回客户端。对于支持随机访问的客户端(如媒体播放器)、知道只需要大型文件一部分的数据工具以及允许用户暂停和恢复下载的下载管理器,范围请求非常有用。
检查服务器是否支持部分请求
如果 HTTP 响应包含 Accept-Ranges
标头,并且其值为除“none
”之外的任何内容,则表示服务器支持范围请求。您可以使用 cURL 等工具发出 HEAD
请求进行手动检查。
curl -I http://i.imgur.com/z4d4kWk.jpg
HTTP/1.1 200 OK
…
Accept-Ranges: bytes
Content-Length: 146515
在此响应中,Accept-Ranges: bytes
表示可以使用字节作为单位来定义范围。此处,Content-Length
标头也很有用,因为它指示要检索的图像的完整大小。
如果站点省略了 Accept-Ranges
标头,则可能不支持部分请求。某些站点包含该标头,但将其显式设置为“none
”以指示它们缺乏支持。
curl -I https://www.youtube.com/watch?v=EwTZ2xpQwpA
HTTP/1.1 200 OK
…
Accept-Ranges: none
在这种情况下,下载管理器可能会禁用其暂停按钮。
向服务器请求特定范围
如果服务器支持范围请求,则通过在 HTTP 请求中包含 Range
标头,您可以指定希望服务器返回的文档的哪一部分或哪些部分。
单部分范围
我们可以从资源中请求单个范围。同样,我们可以使用 cURL 测试请求。“-H
”选项会将标头行附加到请求中,在本例中,它是请求前 1024 个字节的 Range
标头。
curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"
发出的请求如下所示
GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023
服务器使用 206
Partial Content
状态进行响应
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
…
(binary content)
Content-Length
标头现在指示请求范围的大小(而不是图像的完整大小)。Content-Range
响应标头指示此部分消息在完整资源中的位置。
多部分范围
Range
标头还允许您在多部分文档中一次获取多个范围。范围之间用逗号分隔。
curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"
服务器使用 206
Partial Content
状态和 Content-Type
: multipart/byteranges; boundary=3d6b6a416f9b5
标头进行响应,指示接下来是多部分字节范围。每个部分都包含其自己的 Content-Type
和 Content-Range
字段,并且必需的边界参数指定用于分隔每个主体部分的边界字符串。
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 0-50/1270
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Example Do
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-150/1270
eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--
条件范围请求
在恢复请求资源的更多部分时,您需要保证存储的资源自上次接收片段以来未被修改。
If-Range
HTTP 请求标头使范围请求成为条件请求:如果条件满足,则将发出范围请求,并且服务器将使用相应的正文发送 206
Partial Content
响应。如果条件不满足,则将发送完整资源,并使用 200
OK
状态。此标头可以与 Last-Modified
验证器或 ETag
一起使用,但不能同时使用两者。
If-Range: Wed, 21 Oct 2015 07:28:00 GMT
部分请求响应
与分块Transfer-Encoding
的比较
Transfer-Encoding
标头允许分块编码,这在将大量数据发送到客户端并且在完全处理请求之前不知道响应的总大小时非常有用。服务器会立即将数据发送到客户端,而无需缓冲响应或确定确切的长度,从而导致延迟减少。范围请求和分块是兼容的,可以彼此独立使用。
另请参阅
- 相关状态代码
200
、206
、416
。 - 相关标头:
Accept-Ranges
、Range
、Content-Range
、If-Range
、Transfer-Encoding
。