博客地址:https://ainyi.com/88html
對於 Blob,前端開發中可能比較少遇到;數據庫中可以使用 Blob 概念,例如 Mysql 存儲二進制數據的類型就是 Blob,也就是說圖片可存儲於數據庫中,以二進制格式存儲前端
Blob 對象表示一個不可變、原始數據的類文件對象。File 接口基於Blob,繼承了 blob 的功能並將其擴展使其支持用戶系統上的文件ios
Blob 是二進制數據對象,是類文件對象的二進制數據ajax
我在以前有篇博客說到 Blob:利用 Blob 處理 Node 層返回的二進制文件流字符串並下載文件
這裏我利用 Blob 實現文件拆分再合併下載的方法,算是第一次使用sql
咱們最多見的應該是 Blob URL 技術,文件上傳的預覽、視頻播放的 src,均是採用這種技術實現數據庫
Blob URL 就是以 blob: 開頭的一段地址,指向的是一個二進制數據
使用 URL.createObjectURL(blob) 方法生成,參數爲 Blob 對象axios
這個 Blob URL 是能夠直接訪問的;須要注意的是這個 URL 的生效時間,等同於網頁的存在時間,一旦網頁刷新或關閉,這個 Blob URL 就失效後端
Blob(blobParts[, options])
返回一個新建立的 Blob 對象,其內容由參數中給定的數組串聯組成數組
參數說明:
blobParts:數組類型,數組中的每一項鍊接起來構成 Blob 對象的數據,數組中的每項元素能夠是ArrayBuffer, ArrayBufferView, Blob, DOMStringapp
options:可選參數;字典格式類型,能夠指定以下兩個屬性:
介紹三種使用場景
// 獲取文件二進制流 content const content = await downloadContract(params) // 再利用 Buffer 轉爲對象 const buf = Buffer.from(content, 'binary') // 生成 Blob 對象,type 類型設置爲 pdf 的 MIME 類型 const blob = new Blob([buf], {type: 'application/pdf'}); // 獲取 Blob URL,可賦值到 a 標籤 href 屬性進行下載 const url = URL.createObjectURL(blob)
經過 Blob 生成文件、利用 Blob URL 獲取下載連接,這樣就實現後端返回二進制格式的文件進行合併再下載
較爲簡單,獲取文件對象後,再經過 createObjectURL 方法獲得 Blob URL
最後直接賦值到 img 標籤的 src 屬性便可
<input id="upload" type="file" /> <img id="preview" src="" alt="預覽"/>
const upload = document.querySelector('#upload') const preview = document.querySelector('#preview') upload.onchange = function() { const file = upload.files[0] // File 對象 const src = URL.createObjectURL(file) preview.src = src }
視頻地址,不一樣於上面的 input,能夠直接拿到 File 對象
只有一個視頻地址怎麼能將這個 URL 變成咱們想要的 Blob URL 形式呢
從 URL.createObjectURL(blob) 方法來看,首先要拿到存儲這個視頻原始數據的 Blob 對象
平時咱們請求接口可使用 axios / ajax / xhr 或 fetch,請求一個服務端地址能夠返回咱們相應的數據,那若是咱們去請求一個圖片或視頻地址會返回什麼?應當是返回圖片和視頻的數據,這種狀況只要設置正確responseType才能拿到咱們想要的格式數據
// responseType 參數以下: // text 字符串;blob Blob對象;arraybuffer ArrayBuffer 對象 function ajax(url, cb) { const xhr = new XMLHttpRequest() xhr.open('get', url) xhr.responseType = 'blob' xhr.onload = function() { cb(xhr.response) } xhr.send() }
上面請求返回一個 Blob 對象,接下來只要而後經過 createObjectURL 生成 Blob URL 賦值給視頻的 src 屬性就能夠了
ajax('video.mp4', function(res){ const src = URL.createObjectURL(res) video.src = src })
最近看到一篇文章:大規格文件的上傳優化
裏面講的是利用 Blob 實現文件分片上傳,對於大文件上傳有很好的效果
其核心思想是文件分片,使用 File.slice() 方法進行文件分片;File 對象是繼承 Blob 對象的,所以 File 對象也有 slice 方法
Blob.slice([start[, end[, contentType]]])
start 可選
這個參數表明 Blob 裏的下標,表示第一個會被會被拷貝進新的 Blob 的字節的起始位置。若是你傳入的是一個負數,那麼這個偏移量將會從數據的末尾從後到前開始計算
舉例來講: -10 將會是 Blob 的倒數第十個字節。它的默認值是0, 若是你傳入的start的長度大於源 Blob 的長度,那麼返回的將會是一個長度爲0而且不包含任何數據的一個 Blob 對象
end 可選
這個參數表明的是 Blob 的一個下標,這個下標-1的對應的字節將會是被拷貝進新的Blob 的最後一個字節。若是你傳入了一個負數,那麼這個偏移量將會從數據的末尾從後到前開始計算
舉例來講: -10 將會是 Blob 的倒數第十個字節。它的默認值就是它的原始長度(size)
contentType 可選
給新的 Blob 賦予一個新的文檔類型。這將會把它的 type 屬性設爲被傳入的值。它的默認值是一個空的字符串
文件分片方法
定義每個分片文件的大小變量爲 chunkSize,經過文件大小 FileSize 和分片大小 chunkSize 獲得分片數量 chunks,使用 for 循環和 file.slice() 方法對文件進行分片,序號爲 0 - n,和已上傳的切片列表作比對,獲得全部未上傳的分片,push 到請求列表 requestList
上傳進度
監聽原生 Javascript 的 XMLHttpRequest 的 progress 事件,這個事件會返回文件已上傳的大小和總大小,可實現上傳進度的變化
博客地址:https://ainyi.com/88