前端下載文件的幾種方式


1、使用 location.href 

// 適用於瀏覽器無法識別文件,如果是html、jpg、pdf等會直接解析展示,而不會下載

window.location.href = url

 

2、使用 window.open

// 適用於瀏覽器無法識別文件,如果是html、jpg、pdf等會直接解析展示,而不會下載

window.open(url)

 

3、a 標簽

// 適用於單文件下載或需要自定義文件名稱

//寫法1
const download = (filename, url) => {
    let a = document.createElement('a'); 
    a.style = 'display: none'; // 創建一個隱藏的a標簽
    a.download = filename;
    a.href = url;
    document.body.appendChild(a);
    a.click(); // 觸發a標簽的click事件
    document.body.removeChild(a);
}
// 寫法2
< a href="/images/download.jpg" download="myFileName">

 

4、文件流

step1 發送請求,有兩種方式
// 此種方式的優點是支持多文件下載、post下載、自定義文件名稱,流程是向后端發送post請求,后端返回文件流,前端將文件流轉成下載鏈接

// 原生js請求寫法(不可以使用JQuery,因為JQuery不支持blob類型)
function download() {
     const req = new XMLHttpRequest();
    req.open('POST', '/download/excel', true);
    req.responseType = 'blob'; //如果不指定,下載后文件會打不開
    req.setRequestHeader('Content-Type', 'application/json');
    req.onload = function() {
      var content = req.getResponseHeader("Content-Disposition") ;
      // 文件名最好用后端返的Content-disposition
      // 需要后端設置 Access-Control-Expose-Headers: Content-disposition 使得瀏覽器將該字段暴露給前端
      var name = content && content.split(';')[1].split('filename=')[1];
      var fileName = decodeURIComponent(name)
      downloadFile(req.response,fileName)  // 調用將文件流轉成文件的方法,后面有寫
    };
    req.send( JSON.stringify(params));

}

// axios請求寫法
function download() {
  axios({
    method: 'post',
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    },
    url: '/robot/strategyManagement/analysisExcel',
    responseType: 'blob',
    headers: { //如果需要權限下載的話,加在這里
      Authorization: '123456'
    }
    data: JSON.stringify(params),
  }).then(function(res){
    var content = res.headers['content-disposition'];
    var name = content && content.split(';')[1].split('filename=')[1];
    var fileName = decodeURIComponent(name)
    downloadFile(res.data,fileName)// 調用將文件流轉成文件的方法,后面有寫
  }) 
}

 

step2 處理文件流下載

 

  方式一: 通過URL.createObjectURL()下載

// URL.createObjectURL() 靜態方法會創建一個DOMString,其中包含一個表示參數中給出的對象的URL。這個 URL 的生命周期和創建它的窗口中的document綁定

downloadFile:function(data,fileName){
    // data為blob格式
    var blob = new Blob([data]);
    var downloadElement = document.createElement('a');
    var href = window.URL.createObjectURL(blob);
    downloadElement.href = href;
    downloadElement.download = fileName;
    document.body.appendChild(downloadElement);
    downloadElement.click();
    document.body.removeChild(downloadElement);
    window.URL.revokeObjectURL(href);
}

 

  方式二:通過# FileReader.readAsDataURL()下載

// readAsDataURL() 方法會讀取指定的 Blob 或 File 對象。讀取操作為異步操作,當讀取完成時,可以從onload回調函數中通過實例對象的result屬性獲取data:URL格式的字符串(base64編碼),此字符串即為讀取文件的內容,可以放入a標簽的href屬性中
downloadFile:function(data,fileName){
   const reader = new FileReader()
   // 傳入被讀取的blob對象
   reader.readAsDataURL(data)
   // 讀取完成的回調事件
   reader.onload = (e) => {
       let a = document.createElement('a')
       a.download = fileName
       a.style.display = 'none'
       // 生成的base64編碼
       let url = reader.result
       a.href = url
       document.body.appendChild(a)
       a.click()
       document.body.removeChild(a)
   }
}

 

 readAsDataURL 和 createObjectURL 對比

  readAsDataURL (blob) createObjectURL (blob)
返回值 可以得到一段base64的字符串 得到的是當前文件的一個內存url
內存 js垃圾回收機制自動從內存中清理 存在於當前document內,清除方式通過revokeObjectURL()手動清除
執行方式 通過回調的方式f返回,異步執行 直接返回,同步執行
多個文件 同時處理多個文件時,需要一個文件對應一個FileReader對象 依次返回,沒有影響
優勢對比 可直接轉為base64格式,直接用於業務 得到本地內存容器的URL地址,方便預覽,需要注意手動釋放內存的問題,性能優秀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM