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地址,方便預覽,需要注意手動釋放內存的問題,性能優秀 |