HTTP 的 Range 請求使客戶端能夠要求服務器僅向其回傳 HTTP 消息的一部分
HTTP 的 Range 請求頭是 HTTP/1.1 協議的一個特性。它允許客戶端請求僅傳輸資源的某個特定部分,而不是整個資源。
適用場景
- 支持隨機訪問的媒體播放器
- 明確只需大型文件某部分的數據處理工具
- 允許用戶暫停及恢復下載的下載管理器
這對于需要只下載大文件中的一部分數據的應用場景非常有用
檢測服務端是否支持范圍請求
如果 HTTP 響應中存在 Accept-Ranges 標頭,并且其值不是“none”,那么該服務器支持范圍請求
通過使用像 cURL 這樣的工具發出一個 HEAD 請求來進行手動檢查
curl -I http://i.imgur.com/z4d4kWk.jpgHTTP/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
HTTP/1.1 200 OK
... ...
Accept-Ranges: none
下載管理器可能會禁用暫停按鈕
從服務器端請求特定的范圍
如果服務器支持范圍請求,只需在 HTTP 請求中包含 Range 標頭,指定希望服務器返回文檔的哪一部分或哪些部分
單一范圍
使用 cURL 來測試。這里的“-H”選項會向請求中添加一個標頭,即 Range 標頭,用于請求前 1024 個字節
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
... ...
Content-Range 響應標頭,表示此部分消息在完整資源中的位置
Content-Length 標頭,表示所請求范圍的大小(而非完整大小)
多重范圍
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 字段,而必須的 boundary 參數定義了用于分割每個消息體部分的邊界字符串
(邊界字符串…)
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/1270eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--
條件式范圍請求
當重新開始請求資源的更多部分時,需要保證存儲資源在收到上一個片段后未被修改
If-Range: Wed, 21 Oct 2015 07:28:00 GMT
If-Range HTTP 請求標頭使范圍請求具有條件性:
- 如果條件兌現,則會發起范圍請求,服務器將以包含適當內容主體的 206 Partial Content 響應進行回復
- 如果條件不兌現,會被發送完整的資源回來,并帶有 200 OK 狀態
該標頭可與 Last-Modified 驗證器或 ETag 一起使用,但不能同時使用
范圍請求的響應
范圍請求相關的有三種狀態
- 范圍請求成功后,服務器會發出 206 Partial Content 狀態
- 如果不支持范圍請求,則返回 200 OK 狀態,并傳輸完整的響應體
- 超出范圍的范圍請求將導致 416 Requested Range Not Satisfiable 狀態,這意味著沒有任何范圍值與資源的范圍重疊
例如,每個范圍的第一個字節位置可能大于資源的長度
與分塊 Transfer-Encoding 的對比
Transfer-Encoding 標頭支持分塊編碼,這對于向客戶端發送大量數據特別有用,尤其是在完全處理請求之前,無法知道響應總大小的情況。服務器直接向客戶端發送數據,無需確定緩沖響應或確切長度,從而減少延遲提高響應速度
范圍請求和分塊傳輸是兼容的,可以獨立使用或結合使用