文章目錄
前端如何實現文件下載功能
對於如何實現文件下載功能,根據實現的技術方式分爲兩大類:
- 結合後端實現
- 純前端實現
結合後端實現
兩種實現方式
第一種、直接下載服務器的靜態資源
對於這種方式,最簡單的是使用a標籤
<a href="URL"></a>
其他的方法如form
、iframe
、location.href
、window.open()
,這裏就不細講了。
第二種、前端傳參,後端生成文件
實現思路:
1、前端通過發送數據或參數給到後端
2、在由後端根據接收的數據生成文件或根據參數查找出對應的數據在生成文件
3、然後在響應請求頭中設置
Content-disposition:attachment;filename="fliename.fileType"
用於指定文件類型、文件名和文件編碼等
Content-disposition
(內容-部署)是MIME
協議類型的擴展,MIME
協議指示MIME
用戶代理如何顯示附加的文件。
4、瀏覽器接收到響應頭後就會觸發下載行爲。
優缺點
優點
-
可以根據參數生成不同的文件,靈活性高
-
能實現大數據量或大文件的下載
缺點
- 如果需要下載的是用戶生成的內容(在線作圖等)或者內容已經全部返回到客戶端,會造成資源和帶寬的浪費
純前端實現
純前端實現並不是一定不需要後端,只是有時候後端的數據已經給到前端,用戶下載的文件內容只需要現有的數據,這時候就可以是使用純前端實現下載文件的功能來減小服務器資源和帶寬的浪費。
數據來源
1、後端返回
2、用戶輸入:在線作圖、在線表格輸入
實現思路
分爲兩步:
第一步、將數據生成對應得data:URLs
或blob:URLs
第二步、處理下載(或叫導出)方式
第一步、將數據生成對應得data:URLs
或blob:URL
生成data:URLs
data: URLs
是前綴爲data:
的 URL
字符串,格式爲
data:[<mediatype>][;base64],<data>
mediatype
是個 MIME 類型的字符串,例如 "image/jpeg
" 表示 JPEG
圖像文件。
如果被省略,則默認值爲 text/plain;charset=US-ASCII
如何將數據轉換爲data:URLs
第一種、對於文本類型,可以直接將數據拼接
示例
const dataURL = `data:text/plain;base64,` + textData
第二種、通過window.btoa()
方法
btoa()
函數將二進制數據的“字符串”創建base-64編碼的ASCII字符串。
示例
let str = new Blob(['some thing'])
console.log(btoa(str)) // W29iamVjdCBCbG9iXQ==
let dataURL = 'data:text/plain;base64,' + btoa(str) // data:text/plain;base64,W29iamVjdCBCbG9iXQ==
第三種、通過FileReader.readAsDataURL(blob)
方法
對於File
或Blob
對象,可以使用FileReader.readAsDataURL()
的方法轉換爲data:URLs
示例
const blob = new Blob(['some thing'])
const reader = new FileReader()
reader.onloadend = function() {
const dataUrl = is_chrome_ios
? reader.result
: reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;')
}
reader.readAsDataURL(blob)
生成BlobURLs
blob: URLs
是URL.createObjectURL()
靜態方法創建的一個 DOMString
,其中包含一個表示參數中給出的對象的URL
。
URL.createObjectURL()
方法只能處理File
或Blob
對象,所以如果要生成blobURLs
則必須將數據轉換爲blob
對象或file
對象。
示例
如果數據不是File或Blob對象
const blob = new Blob([data][, MIMEType])
生成BlobURLs
const BlobURL = URL.createObjectURL(blob)
創建出來的
BlobURLs
需要手動調用URL.revokeObjectURL()
銷燬,否則會一直保留到頁面關閉,爲了獲得最佳性能和內存使用狀況,你應該在安全的時機主動釋放掉它們。
第二步、處理下載(或叫導出)方式
第一種、<a>
標籤的download
和href
其中<a>
標籤的download
是HTML5
標準新增的屬性,作用是指示瀏覽器下載URL
而不是導航到URL,因此將提示用戶將其保存爲本地文件。另外,download
屬性的值可以指定下載文件的名稱。
href
則支持dataURLs
和blobURLs
兩種類型的值。
示例
<a download="filename" href="dataURLs或BlobURLs"></a>
第二種、location.href
或window.open()
這個方法是直接把 DataURLs
或者 BlobURLs
傳到瀏覽器地址中觸發下載。有兩種方式:
window.location.href = urls; // 本窗口打開下載
window.open(urls, '_blank'); // 新開窗口下載
第三種、msSaveOrOpenBlob(IE10+)
這是 IE
特有的方法。
navigator.msSaveOrOpenBlob(blob, fileName);
第四種、iframe(IE <= 9)
其他更現代的瀏覽器也支持此方法,不過此方法效率和安全性較低,所以一般只在 IE <= 9
時使用。
var frame = document.createElement("iframe");
if ( frame ) {
document.body.appendChild(frame);
frame.setAttribute("style", "display:none");
frame.contentDocument.open("txt/html", "replace");
frame.contentDocument.write(data); // data 是 string 類型
frame.contentDocument.close();
frame.focus();
frame.contentDocument.execCommand("SaveAs", true, filename);
document.body.removeChild(frame);
}
優缺點
優點
- 減少服務器資源和帶寬
- 只需要前端,增加了前端的可控性
缺點
- 對於大數據量支持度不好
- 有兼容性問題