開篇一張圖
前言
項(xiàng)目中經(jīng)常會(huì)遇到需要導(dǎo)出列表內(nèi)容,或者下載文件之類的需求。結(jié)合各種情況,我總結(jié)了前端最常用的三種方法來接受后端傳過來的文件流并下載,針對(duì)不同的情況可以使用不同的方法。
方法一
使用場(chǎng)景
針對(duì)后端的get
請(qǐng)求
具體實(shí)現(xiàn)
<a href="后端文件下載接口地址" >下載文件</a>
直接用個(gè)<a>
標(biāo)簽來接受后端的文件流
方法二
使用場(chǎng)景
針對(duì)后端的post
請(qǐng)求
利用原生的XMLHttpRequest
方法實(shí)現(xiàn)
具體實(shí)現(xiàn)
function request () {
const req = new XMLHttpRequest();
req.open('POST', '<接口地址>', true);
req.responseType = 'blob';
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
const data = req.response;
const a = document.createElement('a');
const blob = new Blob([data]);
const blobUrl = window.URL.createObjectURL(blob);
download(blobUrl) ;
};
req.send('<請(qǐng)求參數(shù):json字符串>');
};
function download(blobUrl) {
const a = document.createElement('a');
a.style.display = 'none';
a.download = '<文件名>';
a.href = blobUrl;
a.click();
document.body.removeChild(a);
}
request();
方法三
使用場(chǎng)景
針對(duì)后端的post
請(qǐng)求
利用原生的fetch
方法實(shí)現(xiàn)
具體實(shí)現(xiàn)
function request() {
fetch('<接口地址>', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: '<請(qǐng)求參數(shù):json字符串>',
})
.then(res => res.blob())
.then(data => {
let blobUrl = window.URL.createObjectURL(data);
download(blobUrl);
});
}
function download(blobUrl) {
const a = document.createElement('a');
a.style.display = 'none';
a.download = '<文件名>';
a.href = blobUrl;
a.click();
document.body.removeChild(a);
}
request();
總結(jié)
- 如果后端提供的下載接口是
get
類型,可以直接使用方法一,簡單又便捷;當(dāng)然如果想使用方法二、三也是可以的,不過感覺有點(diǎn)舍近求遠(yuǎn)了。 - 如果后端提供的下載接口是
post
類型,就必須要用方法二或者方法三了。
方法二和方法三怎么取舍?
- 當(dāng)你的項(xiàng)目里的接口請(qǐng)求全是基于
XMLHttpRequest
實(shí)現(xiàn)的,這時(shí)方法二就更加適合,只要基于你原來項(xiàng)目中的接口請(qǐng)求工具類加以擴(kuò)展就行了。 - 當(dāng)你的項(xiàng)目里的接口請(qǐng)求全是基于
fetch
實(shí)現(xiàn)的,這時(shí)方法三就更加適合,比如我現(xiàn)在的做的一個(gè)項(xiàng)目就是基于ant design pro
的后臺(tái)管理系統(tǒng),它里面的請(qǐng)求類就是基于fetch
的,所以我就直接用的方法三,只要在它的request.js
文件中稍作修改就行。 - 我這里討論的是兩種原生的請(qǐng)求方式,如果你項(xiàng)目中引用了第三方請(qǐng)求包來發(fā)送請(qǐng)求,比如axios之類的,那就要另當(dāng)別論了。