前后端交互时,我们经常遇到前端页面点击下载(导出)按钮,实现一定格式的文件下载到本地,以下介绍项目中遇到的下载方式:
一、使用window.open()
后端会给你调用的接口,只需要传递相应的参数,就可以实现下载(后端会处理吧!),我感觉我们只需要有一个切换页面的效果,就实现下载了。直接上代码吧:
//在页面中点击下载,触发下载请求,调起后端接口
dispatch({
type: 'myData/myDownLoad',
payload: {
year_month: settlementData,
supplier_id: supplierId,
output: type,
},
})
//处理下载的逻辑
*myDownLoad(payload, { select, put, call }) {
let res = '', params = {}
const firter = payload.payload
//这里是为了拼接url,作为window.open()的第一个参数
Object.keys(firter).forEach(key => {
const value = firter[key];
if (value == null) {
return;
}
params[key] = value
})
for (const key in params) {
res += `${key}=${params[key]}&`;//这里将请求的参数拼接为字符串:比如id=2&name=’lili‘
}
let ret = new URLSearchParams(res)
let settlementAmountDownLoadUrl = service.account.settlementAmountDownLoad + '?' + ret.toString();
window.open(settlementAmountDownLoadUrl, '_blank');
},
这里是关于URLSearchParams()的讲解
这里要注意,使用toString才能正确的返回字符串,否则返回的是一个对象


二、通过动态添加超链接
后端提供请求接口,我们只需去触发请求,有的情况是后端提供的接口返回的数据是文件流,需要前端去处理,我遇到的是不需要处理文件流的,可以直接跳过下面的代码,通过后面的超链接查看如何处理文件流下载。
//下载文件名
fileName(url) {
let a = url.split('/')
let fileName = a[a.length - 1]
console.log('fileName', fileName)
return fileName + '.txt'
}
handleDownload = (detailDataList) => {//传递的参数是url地址
const elink = document.createElement('a');
elink.download = this.fileName(detailDataList);//下载的文件名
elink.style.display = 'none';
elink.href = detailDataList;
document.body.appendChild(elink);
elink.click();
// 释放 通过调用 URL.createObjectURL() 创建的 URL 对象
// URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
}
话外篇:URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。createObjectURL() 返回一段带 hash 的 url ,会一直存储在内存中,直到 document 触发了unload事件或者执行 revokeObjectURL() 来释放。