前端通過Blob實現文件下載

  • 2019 年 10 月 3 日
  • 筆記

最近遇到一個需求,需要將頁面中的配置資訊下載下來供用戶方便使用,以前這個場景的需求有時候會放到後端處理,然後給返回一個下載鏈接。其實並不需要這麼麻煩,這樣既增大了伺服器的負載,也讓用戶產生了沒有必要的網路請求,現在前端也是可以直接通過Blob對象進行前端文件下載了,下面簡單記錄下相關實現

Blob對象簡要介紹

Blob 對象表示一個不可變、原始數據的類文件對象。Blob 表示的不一定是JavaScript原生格式的數據。File 介面基於Blob,繼承了 Blob 的功能並將其擴展使其支援用戶系統上的文件。

語法

const aBlob = new Blob( array, options );  

參數說明

  • array 是一個由ArrayBuffer, ArrayBufferView, Blob, DOMString 等對象構成的 Array ,或者其他類似對象的混合體,它將會被放進 Blob。DOMStrings會被編碼為UTF-8。
  • options 是一個可選的BlobPropertyBag字典,它可能會指定如下兩個屬性:
    • type,默認值為 "",它代表了將會被放入到blob中的數組內容的MIME類型。
    • endings,默認值為"transparent",用於指定包含行結束符n的字元串如何被寫入。 它是以下兩個值中的一個: "native",代表行結束符會被更改為適合宿主作業系統文件系統的換行符,或者 "transparent",代表會保持blob中保存的結束符不變

示例

const debug = {hello: "world"};  const blob = new Blob([JSON.stringify(debug, null, 2)],{type : 'application/json'});  

URL.createObjectURL() 與 URL.revokeObjectURL()介紹

URL.createObjectURL() 靜態方法會創建一個 DOMString,其中包含一個表示參數中給出的對象的URL。這個 URL 的生命周期和創建它的窗口中的 document 綁定。這個新的URL 對象表示指定的 File 對象或 Blob 對象。相當於這個方法創建了一個傳入對象的記憶體引用地址

createObjectURL語法

objectURL = URL.createObjectURL(object);

參數說明

  • object 是用於創建 URL 的 File 對象、Blob 對象或者 MediaSource 對象。​

返回值

  • 一個可以引用到指定對象的DOMString

URL.revokeObjectURL() 靜態方法用來釋放一個之前已經存在的、通過調用 URL.createObjectURL() 創建的 URL 對象。當你結束使用某個 URL 對象之後,應該通過調用這個方法來讓瀏覽器知道不用在記憶體中繼續保留對這個文件的引用了。

你可以在 sourceopen 被處理之後的任何時候調用 revokeObjectURL()。這是因為 createObjectURL() 僅僅意味著將一個媒體元素的 src 屬性關聯到一個 MediaSource 對象上去。調用revokeObjectURL() 使這個潛在的對象回到原來的地方,允許平台在合適的時機進行垃圾收集。

revokeObjectURL語法

window.URL.revokeObjectURL(objectURL);

參數說明

  • objectURL 是一個 DOMString,表示通過調用 URL.createObjectURL() 方法產生的 URL 對象。

記憶體管理

在每次調用createObjectURL() 方法時,都會創建一個新的 URL 對象,即使你已經用相同的對象作為參數創建過。當不再需要這些 URL 對象時,每個對象必須通過調用 URL.revokeObjectURL() 方法來釋放。瀏覽器會在文檔退出的時候自動釋放它們,但是為了獲得最佳性能和記憶體使用狀況,你應該在安全的時機主動釋放掉它們。

實際運用

比如在某後台管理中希望將用戶的幾個配置資訊導入到一個json文件當中供用戶下載下來

程式碼實現如下:

const config = {    name: 'lsqy',    password: 'yourpassword',    ak: 'XXXXXXXXXX',    sk: 'XXXXXXXXXX'  }    const blobContent = new Blob(    [JSON.stringify(config, null, 2)],    {type : 'application/json'}  );    const blobUrl = window.URL.createObjectURL(blobContent)    downloadFileByBlob(blobUrl, 'config.json')    function downloadFileByBlob(blobUrl, filename) {    const eleLink = document.createElement('a')    eleLink.download = filename    eleLink.style.display = 'none'    eleLink.href = blobUrl    // 觸發點擊    document.body.appendChild(eleLink)    eleLink.click()    // 然後移除    document.body.removeChild(eleLink)  }    

執行上面的程式碼,我們可以得到一個config.json的文件,可以看到,其實很簡單就實現了這個場景需求,當然這裡是下載的json文件,下載其他的文件也是一樣的道理,只是需要得到相應文件的blob數據,再結合相應的MIME類型即可;

兼容性方面目前主流瀏覽器都已支援,ie10以及以上也支援。

另外Blob結合URL.revokeObjectURL()與URL.revokeObjectURL()還可以用在預覽圖片、預覽PDF、影片鏈接防盜等多種場景中,大家可以發揮自己的想像力來進行實現

參考鏈接

文章首發自個人部落格

Tags: