有三種方法可以縮短通過 HTTP 發送大量資料的時間:
- 壓縮資料
- 發送區塊資料
- 請求選定範圍內的資料
以上三種方法可以組合起來一起使用。在 HTTP 1.1 版引入了區塊資料來幫助處理大量資料情況。
HTTP server 在發送 response 時,會添加一個header, Transfer-Encoding: chunked,讓瀏覽器知道資料是以區塊的形式傳輸。
每個區塊資料由以下部分組成:
- 區塊資料長度
- 區塊資料
- 區塊結尾的 CRLF 分隔符
server持續將區塊資料傳輸到瀏覽器。當到達資料流的末尾時,它會附加一個由以下部分組成的結束標記:
- 一個長度為 0 的區塊,末尾有一個 CRLF
- 額外的 CRLF
瀏覽器會等待所有資料區塊,直到收到結束標記。然後它會刪除區塊編碼,包括 CRLF 和長度信息,將區塊資料組合成,最後成為一份完整的資料。
對於像 5GB 這樣大小的視頻,完整的資料仍然需要一段時間才能完全到達。
我們可以先獲取選定的部分,並在需要時再請求其他部分。例如在 YouTube 上打開一個視頻,會看到一個灰色的進度條正在向前移動。那是 YouTube 請求選定範圍內的資料。這個功能讓使用者可以在時間軸中的任意位置跳轉。當點擊進度條上的點時,瀏覽器將請求特定範圍的視頻資料。
在server上實現範圍請求功能是選擇性實作的。可以在 response header 中找到 Accept-Ranges: bytes。在 YouTube 請求中,任何“播放”請求,都可以找到一個標頭範圍請求,看起來像 Range: bytes=0-80,並且是 0-indexed。
假設一個資料總共有 100 個字節。
- Range: bytes=20 請求從 20 到結尾的範圍,等於 Range: bytes=20-99。
- Range: bytes=-20 請求最後 20 個字節的資料,等於 Range: bytes=80-99。
如果請求的範圍有效,則 server 發送帶有 Content-Range 、驗證資料範圍和總長度的標頭,例如 Content-Range:bytes 70-80/100。
Range request 廣泛用於視頻流和文件下載,在網路中斷後繼續下載文件是一個使用的例子。
範圍請求支持多個範圍,例如,可以從文件中請求兩個範圍:bytes=20-45, 70-80。
multi-range 看起來類似於區塊資料。每個資料包含以下部分:
- 一個邊界(boundary)區塊,指示資料的邊界,以 -- 開頭、 CRLF 結尾
- 兩個header,Content-Type和Content-Range,表示相對應的資料區塊的屬性,以CRLF結尾
- 一個額外的 CRLF 告訴客戶端真正的資料即將到來
- 最後,以 CRLF 結尾的資料區塊
boundary 只是一個看起來像 3d6b6a416f9b5 的隨機字符串,標記不同資料區塊的邊界。最終,主體以一個邊界區塊結束,以一個 -- 開始,以 -- 和一個 CRLF 結束。這部分告訴瀏覽器分為多個部份的資料已經結束。
沒有留言:
張貼留言