前端實(shí)現(xiàn)文件下載常見(jiàn)的幾種方法總結(jié)
以下是工作中前端常見(jiàn)的文件下載的幾種方法。歡迎大家補(bǔ)充指正。
一、location.href
對(duì)于一些瀏覽器無(wú)法識(shí)別的文件格式,可以直接再瀏覽器地址欄輸入url即可觸發(fā)瀏覽器的下載功能。對(duì)于單文件下載沒(méi)有什么問(wèn)題,但是如果下載多文件,點(diǎn)擊過(guò)快就會(huì)重置掉前面的請(qǐng)求。
適用場(chǎng)景:
- get請(qǐng)求
- 單文件下載
window.location.href = url;
二、window.open
和location.href類似
window.open(url);
三、a標(biāo)簽
直接下載僅適用于瀏覽器無(wú)法識(shí)別的文件。如果是瀏覽器支持的文件格式,如html、jpg、png、pdf等,則不會(huì)觸發(fā)文件下載,而是直接被瀏覽器解析并展示,這種情況下,可以使用a標(biāo)簽下載文件,download屬性可以設(shè)置文件名。適用于單文件下載,如果下載多文件,點(diǎn)擊過(guò)快就會(huì)重置掉前面的請(qǐng)求。
適用場(chǎng)景:
- get請(qǐng)求
- 單文件下載
- 需要自定義文件名
//寫法1 const download = (filename, url) => { let a = document.createElement('a'); a.style = 'display: none'; // 創(chuàng)建一個(gè)隱藏的a標(biāo)簽 a.download = filename; a.href = url; document.body.appendChild(a); a.click(); // 觸發(fā)a標(biāo)簽的click事件 document.body.removeChild(a); } // 寫法2 <a href="/images/download.jpg" rel="external nofollow" download="myFileName">
注意:有時(shí)候?qū)τ跒g覽器可識(shí)別的文件格式,我們還是需要直接下載的情況,可以聲明一下文件的header的 Content-Disposition信息,告訴瀏覽器,該鏈接為下載附件鏈接,并且可以聲明文件名。
Content-Disposition: attachment; filename="filename.xls"
四、文件流
如果需要使用post請(qǐng)求,且后端返回是一個(gè)文件流形式,那么前端需要自己將文件流轉(zhuǎn)成鏈接,然后下載。 二進(jìn)制流大概長(zhǎng)這樣:
適用場(chǎng)景:
- post請(qǐng)求
- get請(qǐng)求
- 多文件
1.請(qǐng)求的方式
注意:不可以使用JQuery,因?yàn)镴Query不支持blob類型。
原生js寫法
const req = new XMLHttpRequest(); req.open('POST', '/download/excel', true); req.responseType = 'blob'; //如果不指定,下載后文件會(huì)打不開(kāi) req.setRequestHeader('Content-Type', 'application/json'); req.onload = function() { var content = req.getResponseHeader("Content-Disposition") ; // 文件名最好用后端返的Content-disposition // 需要后端設(shè)置 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寫法
axios({ method: 'post', headers: { 'Content-Type': 'application/json; charset=utf-8' }, url: '/robot/strategyManagement/analysisExcel', responseType: 'blob', headers: { //如果需要權(quán)限下載的話,加在這里 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) })
2.文件下載的方式
通過(guò)URL.createObjectURL()下載
URL.createObjectURL() 靜態(tài)方法會(huì)創(chuàng)建一個(gè)DOMString,其中包含一個(gè)表示參數(shù)中給出的對(duì)象的URL。這個(gè) URL 的生命周期和創(chuàng)建它的窗口中的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); }
通過(guò)# FileReader.readAsDataURL()下載
readAsDataURL() 方法會(huì)讀取指定的 Blob 或 File 對(duì)象。讀取操作為異步操作,當(dāng)讀取完成時(shí),可以從onload回調(diào)函數(shù)中通過(guò)實(shí)例對(duì)象的result屬性獲取data:URL格式的字符串(base64編碼),此字符串即為讀取文件的內(nèi)容,可以放入a標(biāo)簽的href屬性中。
downloadFile:function(data,fileName){ const reader = new FileReader() // 傳入被讀取的blob對(duì)象 reader.readAsDataURL(data) // 讀取完成的回調(diào)事件 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) } }
兩者的區(qū)別
- 返回值 FileReader.readAsDataURL(blob)可以得到一段base64的字符串。
URL.createObjectURL(blob)得到的是當(dāng)前文件的一個(gè)內(nèi)存URL
。 - 內(nèi)存 FileReader.readAsDataURL(blob)依照js垃圾回收機(jī)制自動(dòng)從內(nèi)存中清理。 URL.createObjectURL(blob)存在于當(dāng)前document內(nèi),清除方式通過(guò)revokeObjectURL()手動(dòng)清除。
- 執(zhí)行方式 FileReader.readAsDataURL(blob)通過(guò)回調(diào)的方式f返回,異步執(zhí)行。
URL.createObjectURL(blob) 直接返回,同步執(zhí)行。 - 多個(gè)文件 FileReader.readAsDataURL(blob)同時(shí)處理多個(gè)文件時(shí),需要一個(gè)文件對(duì)應(yīng)一個(gè)FileReader對(duì)象URL.createObjectURL(blob) 依次返回,沒(méi)有影響。
- 優(yōu)勢(shì)對(duì)比 URL.createObjectURL(blob)得到本地內(nèi)存容器的
URL
地址,方便預(yù)覽,需要注意手動(dòng)釋放內(nèi)存的問(wèn)題,性能優(yōu)秀。
FileReader.readAsDataURL(blob)可直接轉(zhuǎn)為base64
格式,直接用于業(yè)務(wù)。
總結(jié)
到此這篇關(guān)于前端實(shí)現(xiàn)文件下載常見(jiàn)的幾種方法的文章就介紹到這了,更多相關(guān)前端文件下載方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS嵌套函數(shù)調(diào)用上下文的問(wèn)題解決
這篇文章主要探討了JS嵌套函數(shù)調(diào)用上下文的問(wèn)題,需要的朋友可以參考下2014-03-03JavaScript中Set和Map數(shù)據(jù)結(jié)構(gòu)使用場(chǎng)景詳解
這篇文章主要為大家介紹了JavaScript中Set和Map數(shù)據(jù)結(jié)構(gòu)使用場(chǎng)景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06微信小程序template模板引入的問(wèn)題小結(jié)
這篇文章主要介紹了微信小程序template模板引入的問(wèn)題小結(jié),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07Bootstrap實(shí)現(xiàn)基于carousel.js框架的輪播圖效果
這篇文章主要為大家詳細(xì)介紹了Bootstrap實(shí)現(xiàn)基于carousel.js框架的輪播圖效果,無(wú)過(guò)渡動(dòng)畫(huà),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05JavaScript實(shí)現(xiàn)京東放大鏡效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)京東放大鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12JavaScript使用ActiveXObject訪問(wèn)Access和SQL Server數(shù)據(jù)庫(kù)
這篇文章主要介紹了JavaScript使用ActiveXObject訪問(wèn)Access和SQL Server數(shù)據(jù)庫(kù),本文分別給出相應(yīng)操作代碼,需要的朋友可以參考下2015-04-04JavaScript實(shí)現(xiàn)圖片偽異步上傳過(guò)程解析
這篇文章主要介紹了javascript實(shí)現(xiàn)圖片偽異步上傳過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04