日常开发中我们常常需要下载文件,但是后端返回给前端需要下载的文件大致有两种:一种url链接,另一种文件流的形式;
1、前端下载url链接文件
方法1、通过a标签的href直接下载
<a href="https://www.baidu.com/img/bd_logo1.png" download="logo"></a>
方法2、通过 window.open(url)
直接下载
window.open("https://www.baidu.com/img/bd_logo1.png")
2、前端处理 文件流 文件
针对文件流文件,前端需要进行文件类型,blob处理以后通过动态创建a标签的形式下载
Blob对象处理
MDN上描述
:Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。 要从其他非blob对象和数据构造一个 Blob,请使用 Blob() 构造函数
需要利用Blob()构造函数构建一个blob对象,axios请求例子:
axios.get( url, params ).then((res) => {
const data = res.data;
const url = window.URL.createObjectURL(new Blob([data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}))
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.setAttribute('download', 'excel.xlsx')
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
this.dialogInfo.dialogVisible = false
}).catch((err) => {
console.log(err.message);
});
注意:上面的方法虽然可以下载文件,但是下载下来的文件是乱码,甚至打开文件出错。
花了一个上午的时间找问题,结果接口链接直接在浏览器中,通过a标签下载都能直接打开并下载文件,且文件数据没有任何问题。但是通过axios请求拿到的数据浏览器不识别,且通过blob和动态创建a标签不能下载正确的文件内容,百思不得其解。。。
后来发现是参数 responseType
的问题,responseType 它是服务器响应的数据类型,由于后台返回来的是二进制数据,所以我们要把它设为arraybuffer
或者blob
。
axios.get(url, {
params,
responseType: 'arraybuffer'
}).then((res) => {
const data = res.data;
const url = window.URL.createObjectURL(new Blob([data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}))
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.setAttribute('download', 'excel.xlsx')
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
this.dialogInfo.dialogVisible = false
}).catch((err) => {
console.log(err.message);
});
最后发现文件数据下载成功,文件能够直接打开且数据内容没有问题