了解 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 物件。