關於 Blob

博客地址:https://ainyi.com/88html

對於 Blob,前端開發中可能比較少遇到;數據庫中可以使用 Blob 概念,例如 Mysql 存儲二進制數據的類型就是 Blob,也就是說圖片可存儲於數據庫中,以二進制格式存儲前端

Blob 對象表示一個不可變、原始數據的類文件對象。File 接口基於Blob,繼承了 blob 的功能並將其擴展使其支持用戶系統上的文件ios

Blob 是二進制數據對象,是類文件對象的二進制數據ajax

我在以前有篇博客說到 Blob:利用 Blob 處理 Node 層返回的二進制文件流字符串並下載文件
這裏我利用 Blob 實現文件拆分再合併下載的方法,算是第一次使用sql


咱們最多見的應該是 Blob URL 技術,文件上傳的預覽、視頻播放的 src,均是採用這種技術實現數據庫

WechatIMG6.png

WechatIMG5.png

Blob URL 就是以 blob: 開頭的一段地址,指向的是一個二進制數據
使用 URL.createObjectURL(blob) 方法生成,參數爲 Blob 對象axios

這個 Blob URL 是能夠直接訪問的;須要注意的是這個 URL 的生效時間,等同於網頁的存在時間,一旦網頁刷新或關閉,這個 Blob URL 就失效後端

構造函數

Blob(blobParts[, options])

返回一個新建立的 Blob 對象,其內容由參數中給定的數組串聯組成數組

參數說明:
blobParts:數組類型,數組中的每一項鍊接起來構成 Blob 對象的數據,數組中的每項元素能夠是ArrayBuffer, ArrayBufferView, Blob, DOMStringapp

options:可選參數;字典格式類型,能夠指定以下兩個屬性:

  1. type:放入到 blob 中的數組內容的 MIME 類型 MIME 參考手冊
  2. endings:用於指定包含行結束符\n的字符串如何被寫入;可設置值:native、transparent;native:表示行結束符會被更改成適合宿主操做系統文件系統的換行符; transparent:表示會保持blob中保存的結束符不變;默認值爲 transparent;

使用場景

介紹三種使用場景

  1. 二進制流文件下載
  2. 圖片預覽
  3. 視頻加載

二進制流文件下載

// 獲取文件二進制流 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

相關文章
相關標籤/搜索