Blob(Binary Large Object)表示二進制類型的大對象。在數據庫管理系統中,將二進制數據存儲為一個單一個體的集合。Blob 通常是影像、聲音或多媒體文件。「在 JavaScript 中 Blob 類型的對象表示不可變的類似文件對象的原始數據。」
Blob
由一個可選的字符串 type
(通常是 MIME 類型)和 blobParts
組成:

❝
MIME(Multipurpose Internet Mail Extensions)多用途互聯網郵件擴展類型,是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,瀏覽器會自動使用指定應用程序來打開。多用於指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。
常見的 MIME 類型有:超文本標記語言文本 .html text/html、PNG圖像 .png image/png、普通文本 .txt text/plain 等。
❞
為了更直觀的感受 Blob 對象,我們先來使用 Blob 構造函數,創建一個 myBlob 對象,具體如下圖所示:

如你所見,myBlob 對象含有兩個屬性:size 和 type。其中 size
屬性用於表示數據的大小(以字節為單位),type
是 MIME 類型的字符串。Blob 表示的不一定是 JavaScript 原生格式的數據。比如 File
接口基於 Blob
,繼承了 blob 的功能並將其擴展使其支持用戶系統上的文件。
2.2 Blob URL/Object URL
Blob URL/Object URL 是一種偽協議,允許 Blob 和 File 對象用作圖像,下載二進制數據鏈接等的 URL 源。在瀏覽器中,我們使用 URL.createObjectURL
方法來創建 Blob URL,該方法接收一個 Blob
對象,並為其創建一個唯一的 URL,其形式為 blob:<origin>/<uuid>
,對應的示例如下:
blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641
瀏覽器內部為每個通過 URL.createObjectURL
生成的 URL 存儲了一個 URL → Blob 映射。因此,此類 URL 較短,但可以訪問 Blob
。生成的 URL 僅在當前文檔打開的狀態下才有效。但如果你訪問的 Blob URL 不再存在,則會從瀏覽器中收到 404 錯誤。
上述的 Blob URL 看似很不錯,但實際上它也有副作用。雖然存儲了 URL → Blob 的映射,但 Blob 本身仍駐留在內存中,瀏覽器無法釋放它。映射在文檔卸載時自動清除,因此 Blob 對象隨后被釋放。但是,如果應用程序壽命很長,那不會很快發生。因此,如果我們創建一個 Blob URL,即使不再需要該 Blob,它也會存在內存中。
針對這個問題,我們可以調用 URL.revokeObjectURL(url)
方法,從內部映射中刪除引用,從而允許刪除 Blob(如果沒有其他引用),並釋放內存。
2.3 Blob vs ArrayBuffer
其實在前端除了 「Blob 對象」 之外,你還可能會遇到 「ArrayBuffer 對象」。它用於表示通用的,固定長度的原始二進制數據緩沖區。你不能直接操縱 ArrayBuffer 的內容,而是需要創建一個 TypedArray 對象或 DataView 對象,該對象以特定格式表示緩沖區,並使用該對象讀取和寫入緩沖區的內容。
Blob 對象與 ArrayBuffer 對象擁有各自的特點,它們之間的區別如下:
-
除非你需要使用 ArrayBuffer 提供的寫入/編輯的能力,否則 Blob 格式可能是最好的。
-
Blob 對象是不可變的,而 ArrayBuffer 是可以通過 TypedArrays 或 DataView 來操作。
-
ArrayBuffer 是存在內存中的,可以直接操作。而 Blob 可以位於磁盤、高速緩存內存和其他不可用的位置。
-
雖然 Blob 可以直接作為參數傳遞給其他函數,比如
window.URL.createObjectURL()
。但是,你可能仍需要 FileReader 之類的 File API 才能與 Blob 一起使用。 -
Blob 與 ArrayBuffer 對象之間是可以相互轉化的:
-
使用 FileReader 的
readAsArrayBuffer()
方法,可以把 Blob 對象轉換為 ArrayBuffer 對象; -
使用 Blob 構造函數,如
new Blob([new Uint8Array(data]);
,可以把 ArrayBuffer 對象轉換為 Blob 對象。
在前端 AJAX 場景下,除了常見的 JSON 格式之外,我們也可能會用到 Blob 或 ArrayBuffer 對象:
function GET(url, callback) { let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; // or xhr.responseType = "blob"; xhr.send(); xhr.onload = function(e) { if (xhr.status != 200) { alert("Unexpected status code " + xhr.status + " for " + url); return false; } callback(new Uint8Array(xhr.response)); // or new Blob([xhr.response]); };}
在以上示例中,通過為 xhr.responseType 設置不同的數據類型,我們就可以根據實際需要獲取對應類型的數據了。介紹完上述內容,下面我們先來介紹目前應用比較廣泛的 HLS 流媒體傳輸協議。