前端開發(fā)中,經(jīng)常遇到文件下載的功能。這里對常見的文件下載方式做一些總結(jié)。
一、直接下載
針對一些瀏覽器無法識別的文件格式??梢灾苯釉诘刂窓谏铣鋈險(xiǎn)RL即可觸發(fā)瀏覽器的下載功能。
同類的還有window.location.href、window.open
- 地址欄輸入文件URL
- window.location.href = URL
- window.open(URL)
二、直接下載(使用a標(biāo)簽download屬性)
直接下載僅使用的瀏覽器無法識別的文件。如果是瀏覽器支持的文件格式(如:html、jpg、png)等。則不會觸發(fā)文件下載,而是被瀏覽器直接觸發(fā)解析展示。
針對這種情況,我們可以使用a標(biāo)簽的download屬性,可以設(shè)置文件名。
寫法如下:
<a href="/images/download.jpg" download="myFileName">
開發(fā)中,我們遇到的還有一部分場景是js直接觸發(fā)下載,也是相同的做法,我們可以手動(dòng)寫一個(gè)a標(biāo)簽。appen到body里邊,觸發(fā)下載之后,將其remove
示例如下(生產(chǎn)環(huán)境注意各瀏覽器事件的兼容性寫法):
const download = (filename, link) => {
let DownloadLink = document.createElement('a');
DownloadLink.style = 'display: none'; // 創(chuàng)建一個(gè)隱藏的a標(biāo)簽
DownloadLink.download = filename;
DownloadLink.href = link;
document.body.appendChild(DownloadLink);
DownloadLink.click(); // 觸發(fā)a標(biāo)簽的click事件
document.body.removeChild(DownloadLink);
}
生產(chǎn)環(huán)境可以使用我封裝的itools.js中的download方法。
三、直接下載(后端兼容處理attachment)
有很多場景。有些瀏覽器可識別的文件格式,我們還是需要直接下載的情況(如:用戶直接分享的下載pdf、txt;很多瀏覽器也是支持展示的)。
這種情況下,我們需要聲明一下文件的header的 Content-Disposition信息。告訴瀏覽器,該鏈接為下載附件鏈接,并且可以聲明文件名(方式二也可以下載該類型文件,不過文件名會以header設(shè)置的文件名優(yōu)先)。
寫法如下:
Content-Disposition: attachment; filename="filename.xls"
同類的方法還有將文件作為outstream返回
四、鑒權(quán)下載
在部分場景中,有一些文件,需要用戶登錄之后根據(jù)權(quán)限來開放下載(報(bào)表等)。
此時(shí),我們需要將本地的用戶信息傳給服務(wù)端。常用的方式如:在header增加token。
這里我們需要使用XmlHttpRequest來想后臺發(fā)起請求。并帶上header信息,獲取到文件數(shù)據(jù)之后,在使用下載方法。
axios示例如下:
axios({
method:'get',
url: '/download/file.doc'
responseType: 'blob',
headers: {
Authorization: '123456'
}
}).then(res => {
let fileUrl = window.URL.createObjectURL(res.data)
iTools.download('filename',fileUrl) // 方法二使用到的a標(biāo)簽download方式。
window.URL.revokeObjectURL(fileUrl)
})
原生寫法自己可以百度一下
其他
以上就是常用的文件形式,不過在使用上這些形式還能有其他的使用形式。
- 使用iframe來下載一類型
- 使用post提交表單來做鑒權(quán)
測試代碼
測試代碼倉庫地址:
git clone https://github.com/shb190802/front-end-file-download.git
cd front-end-file-download
npm install
node app.js
// 瀏覽器打卡 http://localhost:3000
