了解 Blob 是什麼以及如何使用它

網頁瀏覽器實作了 Blob 物件,它可以負責存儲數據。

Blob 代表「二進制大型物件」,它是不透明的一組字節。

Blob 可用於許多用途。

它們可以從網路內容中創建,可以保存到磁盤中,或從磁盤中讀取。它們是 FileReader API 中使用的 File 的基礎數據結構,例如。

Blob 可以使用通道消息 API 在 Web Workers 和 iframe 之間進行傳遞,也可以使用推送 API 從服務器傳遞到客戶端。

Blob 也可以使用 URL 來引用。

您可以提取存儲在 Blob 中的文本(或字節),並且 Blob 甚至可以直接存儲在 IndexedDB 中,同樣可以從那裡檢索出來。

查看我的 IndexedDB 教程

Blob 是一種重要的數據類型需要理解。

可以通過以下方式創建 Blob:

  • 使用 Blob() 構造函數
  • 使用 Blob.slice() 實例方法從另一個 Blob 中創建

構造函數接受一個值的數組。即使只有一個要放入 Blob 中的字符串,也必須將其包裹在數組中。

例如:

const data = new Blob(['Test'])

您不需要放入 [String] 值。您可以傳遞:

  • 字符串
  • ArrayBuffer
  • ArrayBufferView
  • 其它 blobs

Blob 构造函數接受可選的第二個參數,它代表 MIME 類型:

const data = new Blob(['Test'], { type: 'text/plain' })

一旦有了 Blob 物件,您可以訪問其 2 個屬性:

  • size 返回 Blob 內容的字節長度
  • type 與其關聯的 MIME 類型

您還可以調用它的唯一方法,slice()。

當您調用 slice() 時,可以檢索 Blob 的一部分。

這是從 aBlob 的第 10-20 字節創建一個新的 Blob 的例子:

const partialBlob = aBlob.slice(10, 20);

上傳 Blob

以下代碼用於作為輸入類型或拖放的回調。我們使用 XMLHttpRequest 將 Blob 加載到網址,使用一個 f 函數來跟踪進度:

const uploadBlob = (url, blob, trackProgress) => {
 const xhr = new XMLHttpRequest()
 xhr.open('POST', url)
 xhr.send(blob)
 xhr.upload.onprogress = trackProgress
}

從互聯網上以 Blob 的形式下載數據

我們可以使用以下語法從互聯網下載數據並將其存儲到 Blob 物件中:

const downloadBlob = (url, callback) => {
 const xhr = new XMLHttpRequest()
 xhr.open('GET', url)
 xhr.responseType = 'blob'

 xhr.onload = () => {
     callback(xhr.response)
 }

 xhr.send(null)
}

Blob URL

我們提到過 Blob 也可以使用 URL 引用。

Blob URL 是由瀏覽器生成的內部引用。給定一個 Blob,您可以使用 URL.createObjectURL() 函數來生成一個指向它的 URL。

Blob URL 以「blob://」為起始。

一旦瀏覽器看到該 URL,它將提供在內存或磁盤中存儲的相應 Blob。

Blob URL 與 Data URL(以「data:」開始)不同,因為它們不將數據存儲在 URL 中。它們也與文件 URL(以「file:」開始)不同,因為它們不會顯示像文件路徑這樣的敏感信息。

如果訪問的 Blob URL 不再存在,您將收到瀏覽器的 404 錯誤。

一旦生成了 Blob URL,可以通過調用 URL.revokeObjectURL() 並傳遞 URL 來刪除它。

以下是從本地磁盤上的頁面加載文件並獲取 Blob 的示例代碼:

<input type="file" accept="image/*" />
const input = document.querySelector('input')

input.addEventListener('change', e => {
 const img = document.createElement('img')
 const imageBlob = URL.createObjectURL(input.files[0])
 img.src = imageBlob

 img.onload = function() {
     URL.revokeObjectURL(imageBlob)
 }

 input.parentNode.replaceChild(img, input)
})

從 Blob 中讀取

無法直接訪問 Blob 中包含的數據。

要能夠這樣做,我們必須使用 FileReader 物件。