前端如何實現文件下載功能

前端如何實現文件下載功能

對於如何實現文件下載功能,根據實現的技術方式分爲兩大類:

  • 結合後端實現
  • 純前端實現

結合後端實現

兩種實現方式

第一種、直接下載服務器的靜態資源

對於這種方式,最簡單的是使用a標籤

<a href="URL"></a>

其他的方法如formiframelocation.hrefwindow.open(),這裏就不細講了。

第二種、前端傳參,後端生成文件

實現思路:

1、前端通過發送數據或參數給到後端

2、在由後端根據接收的數據生成文件或根據參數查找出對應的數據在生成文件

3、然後在響應請求頭中設置

Content-disposition:attachment;filename="fliename.fileType"

​ 用於指定文件類型、文件名和文件編碼等

Content-disposition(內容-部署)是MIME協議類型的擴展,MIME協議指示MIME用戶代理如何顯示附加的文件。

4、瀏覽器接收到響應頭後就會觸發下載行爲。

優缺點

優點

  • 可以根據參數生成不同的文件,靈活性高

  • 能實現大數據量或大文件的下載

缺點

  • 如果需要下載的是用戶生成的內容(在線作圖等)或者內容已經全部返回到客戶端,會造成資源和帶寬的浪費

純前端實現

純前端實現並不是一定不需要後端,只是有時候後端的數據已經給到前端,用戶下載的文件內容只需要現有的數據,這時候就可以是使用純前端實現下載文件的功能來減小服務器資源和帶寬的浪費。

數據來源

1、後端返回

2、用戶輸入:在線作圖、在線表格輸入

實現思路

分爲兩步:

第一步、將數據生成對應得data:URLsblob:URLs

第二步、處理下載(或叫導出)方式

第一步、將數據生成對應得data:URLsblob: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)方法

對於FileBlob對象,可以使用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: URLsURL.createObjectURL() 靜態方法創建的一個 DOMString,其中包含一個表示參數中給出的對象的URL

URL.createObjectURL()方法只能處理FileBlob對象,所以如果要生成blobURLs則必須將數據轉換爲blob對象或file對象。

示例

如果數據不是File或Blob對象
const blob = new Blob([data][, MIMEType])
生成BlobURLs
const BlobURL = URL.createObjectURL(blob)

創建出來的BlobURLs需要手動調用URL.revokeObjectURL()銷燬,否則會一直保留到頁面關閉,爲了獲得最佳性能和內存使用狀況,你應該在安全的時機主動釋放掉它們。

第二步、處理下載(或叫導出)方式

第一種、<a>標籤的downloadhref

其中<a>標籤的downloadHTML5標準新增的屬性,作用是指示瀏覽器下載URL而不是導航到URL,因此將提示用戶將其保存爲本地文件。另外,download屬性的值可以指定下載文件的名稱。

href則支持dataURLsblobURLs兩種類型的值。

示例

<a download="filename" href="dataURLs或BlobURLs"></a>

第二種、location.hrefwindow.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);
}

優缺點

優點

  • 減少服務器資源和帶寬
  • 只需要前端,增加了前端的可控性

缺點

  • 對於大數據量支持度不好
  • 有兼容性問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章