當下載電影時,我經常會想中斷下載後,爲何點擊開始時會在中斷的地方繼續下載呢?
又或者在看在線電影時,爲何能夠按着播放條拖動就能看到想看的片斷呢?node
http的range請求將解決以上困惑。git
一、客戶端明確任務:從哪開始下載github
二、下載文件的指定部份內容
三、下載完畢後拼裝成統一的文件bash
在RFC7233中有詳細介紹
一、容許服務器基於客戶端的請求只發送響應包體的一部分給到客戶端,而客戶端自動將多個片斷的包體組合成完整的體積更大的包體。服務器
二、服務器經過Accept-Range頭部表示是否支持Range請求多線程
基於字節爲單位的時候,舉例:設置響應體長度爲10000併發
經過Range頭部傳遞請求範圍,如:Range: bytes=0-499curl
下面用一些小例子有測試一下。
用node搭了一個簡單的服務器,返回的數字是22個字節的響應體post
'Hello World 0123456789';
複製代碼
如今用curl命令獲取所有的響應體,而後訪問0-5的字節段: 測試
-H參數添加 HTTP 請求的標頭。
上面的命令就是添加HTTP頭Range: bytes=0-5。
返回的是Hello (加上空格)一共六個字節。
如今獲取第21個字節及之後的字節段,就能夠用20-:
返回的是89
下面用etag測試一下Range條件請求
首先獲取0-5字節段
而後用-I來看看生成Hello 時服務器生成Etag的值
接下來,用這個值放到If-Match中獲取6-10字節段:World
若是Etag發生了變化,來看看結果會怎麼樣,將最後的0改成1
返回412 Precondition Failed
經過條件請求能夠判斷兩次下載之間,服務器端資源有沒有發生變化。若是發生了變化,就能夠經過412這個響應知道,資源已經發生了變化。
若是隻獲取部分的body,那麼服務器端返回的響應碼不是200,而是206。
206 Partial Content
Content-Range頭部:顯示當前片斷響應體在完整包體中的位置
Content-Range = byte-content-range / other-content-range
{ btye-content-range = bytes-unit SP (byte-range-resp / unsatisfied-range)
byte-range-resp = byte-range '/' (complete-length / '')
complete-length = 1DIGIT // 完整資源的大小,若是未知則用*號替代
bytr-range = first-byte-pos "-" last-byte-pos }
例如:
一、Content-Range: bytes 42-1233/1234
二、Content-Range: bytes 42-1233/*
用一個視頻播放的例子來看看206響應的樣子。
416 Range Not Statisfiable
若是獲取範圍超出實際資源的大小,好比獲取30-40。返回416
200 OK
獲取5-10, 10-15片斷。
一、客戶端經過Range頭部傳遞請求範圍
二、服務端返回Accept-Range頭部表示是否支持Range請求。
三、客戶端若是在獲得Range響應的一部分,並想在這部分響應未過時的狀況下,獲取其餘部分的響應,能夠用If-Range頭部使用Etag或者Last-Modified爲值。
四、只獲取部分的body,服務器返回206響應碼,其中Content-Range頭部顯示當前片斷響應體在完整包體中的位置
五、客戶端想多重範圍下載資源,在Range頭部的格式爲Range: bytes=0-50, 100-150...(用逗號分隔)
響應頭部Content-Type: multipart/byteranges; boundary=...
更多文章請移步樓主github,若是喜歡請點一下star,對做者也是一種鼓勵