HTTP 範圍請求

HTTP Range 請求要求伺服器僅將 HTTP 訊息的一部分發送回客戶端。對於支援隨機訪問的客戶端(如媒體播放器)、知道只需要大型檔案一部分的資料工具以及允許使用者暫停和恢復下載的下載管理器,範圍請求非常有用。

檢查伺服器是否支援部分請求

如果 HTTP 響應包含 Accept-Ranges 標頭,並且其值為除“none”之外的任何內容,則表示伺服器支援範圍請求。您可以使用 cURL 等工具發出 HEAD 請求進行手動檢查。

bash
curl -I http://i.imgur.com/z4d4kWk.jpg
http
HTTP/1.1 200 OKAccept-Ranges: bytes
Content-Length: 146515

在此響應中,Accept-Ranges: bytes 表示可以使用位元組作為單位來定義範圍。此處,Content-Length 標頭也很有用,因為它指示要檢索的影像的完整大小。

如果站點省略了 Accept-Ranges 標頭,則可能不支援部分請求。某些站點包含該標頭,但將其顯式設定為“none”以指示它們缺乏支援。

bash
curl -I https://www.youtube.com/watch?v=EwTZ2xpQwpA
http
HTTP/1.1 200 OKAccept-Ranges: none

在這種情況下,下載管理器可能會停用其暫停按鈕。

向伺服器請求特定範圍

如果伺服器支援範圍請求,則透過在 HTTP 請求中包含 Range 標頭,您可以指定希望伺服器返回的文件的哪一部分或哪些部分。

單部分範圍

我們可以從資源中請求單個範圍。同樣,我們可以使用 cURL 測試請求。“-H”選項會將標頭行附加到請求中,在本例中,它是請求前 1024 個位元組的 Range 標頭。

bash
curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"

發出的請求如下所示

http
GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023

伺服器使用 206 Partial Content 狀態進行響應

http
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
…
(binary content)

Content-Length 標頭現在指示請求範圍的大小(而不是影像的完整大小)。Content-Range 響應標頭指示此部分訊息在完整資源中的位置。

多部分範圍

Range 標頭還允許您在多部分文件中一次獲取多個範圍。範圍之間用逗號分隔。

bash
curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"

伺服器使用 206 Partial Content 狀態和 Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5 標頭進行響應,指示接下來是多部分位元組範圍。每個部分都包含其自己的 Content-TypeContent-Range 欄位,並且必需的邊界引數指定用於分隔每個主體部分的邊界字串。

http
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 一起使用,但不能同時使用兩者。

http
If-Range: Wed, 21 Oct 2015 07:28:00 GMT

部分請求響應

在處理範圍請求時,有三個相關的狀態

  • 成功的範圍請求會從伺服器獲取 206 Partial Content 狀態。
  • 超出範圍的範圍請求將導致 416 Requested Range Not Satisfiable 狀態,這意味著沒有一個範圍值與資源的範圍重疊。例如,每個範圍的第一個位元組位置都可能大於資源長度。
  • 如果不支援範圍請求,則會發送 200 OK 狀態,並傳輸整個響應正文。

與分塊Transfer-Encoding 的比較

Transfer-Encoding 標頭允許分塊編碼,這在將大量資料傳送到客戶端並且在完全處理請求之前不知道響應的總大小時非常有用。伺服器會立即將資料傳送到客戶端,而無需緩衝響應或確定確切的長度,從而導致延遲減少。範圍請求和分塊是相容的,可以彼此獨立使用。

另請參閱