最近遇到一個需求,需要將頁面中的配置信息下載下來供用戶方便使用,以前這個場景的需求有時候會放到后端處理,然后給返回一個下載鏈接。其實並不需要這么麻煩,這樣既增大了服務器的負載,也讓用戶產生了沒有必要的網絡請求,現在前端也是可以直接通過
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. createObjectURL()
與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
文章首發自個人博客