前端通過Blob實現檔案下載
最近遇到一個需求,需要將頁面中的配置資訊下載下來供使用者方便使用,以前這個場景的需求有時候會放到後端處理,然後給返回一個下載連結。其實並不需要這麼麻煩,這樣既增大了伺服器的負載,也讓使用者產生了沒有必要的網路請求,現在前端也是可以直接通過
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、視訊連結防盜等多種場景中,大家可以發揮自己的想象力來進行實現
參考連結
- https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
- https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
- https://developer.mozilla.org/zh-CN/docs/Web/API/File/Using_files_from_web_applications
- https://developer.mozilla.org/zh-CN/docs/Web/API/URL/revokeObjectURL
文章首發自個人部落格