工作中经常会遇到下载功能,后端有时返回一个文件服务器地址,有时候直接返回文件流。自己对这一块也比较模糊,跟着度娘每次艰难的实现功能。痛定思痛,对下载功能进行一下小小的研究,做一个记录,也希望帮到有需要的小伙伴。
如果是实现同源文件的下载可以直接通过a标签的download来实现,这个就比较简单
a标签
<a href="http://www.XXXX.com" download="XXXX.html">下载</a>
download是h5新增的属性,在这里进行一下说明,后面内容会用到。这个属性用来指定下载文件的名字。想要深入了解可以查看文档。
const a = document.createElement('a')
a.href = 'http://XXX.baidu.com'
a.download = 'XXX.html'
a.click()
如果不想在页面上显示a标签可以通过动态生成的方式来实现。
window.open()
window.open('http://www.XXX.com', '_blank')
// _black用来指定在新页面打开,不指定在当前页面打开
这种方式不能下载.html、.htm、.xml、.xhtml等文件。
如果是同源文件下载用以上方法简单明了,其实说白了,前端的文件下载都是基于浏览器机制。
对于跨域文件的下载,做以下几种说明。
我们在做项目中,经常会把接口放在一个js文件中进行统一管理,我的项目是vue、axios,代码仅作参考。
export function api(data) {
return request({
responseType: 'blob', // *responseType设置为 blob*
url: '/xxxx/xxxxxxxx',// 接口地址
method: 'post',
data
});
}
与正常接口写法一直,多写一行 responseType: ‘blob’。接下来就是正常的调接口环节,使用async/await或者promise都可,看个人习惯。
api(data).then(res => {
if (res) {
let index = res.data[0].uploadFilePath.indexOf('.')
let type = res.data[0].uploadFilePath.substring(index + 1)
let filename = res.data[0].uploadFileName
var a= document.createElement('a');
a.download = filename + '.' + type;
// 指定文件名,根据实际情况指定
var blob = new Blob([res], { type: 'application/x-msdownload' });
a.href = URL.createObjectURL(blob);
document.body.appendChild(a);
a.click(); // 点击创建的a标签
document.body.removeChild(a);// 移除a标签,用完释放是一个好习惯
} else {
this.$message.error('下载异常');
}
}).catch(err => {
console.log(err);
});
这里涉及到blob 和URL.createObjectURL两个点,做一个简单说明
Blob对象
Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。
创建中使用了type属性,其实Blob有两个属性(size和type),size属性是表述文件的大小,type 是 MIME 类型的字符串。
URL.createObjectURL
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL
的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。
这个方法是将Blob对象转化成一个url,通过这个url实现下载。
ajax
通过ajax也是几乎一样的写法
const x = new XMLHttpRequest()
x.open('GET', url, true)
x.responseType = 'blob' // 指定responseType
x.onload = function () {
const url = window.URL.createObjectURL(x.response)
const a = document.createElement('a')
a.href = url
a.download = filename + '.' + type
a.click()
}
x.send()
总结来说,就是将请求回来的文件流转化成Blob对象,然后将Blob对象转化成一个url,通过a标签的形式进行点击下载。
通过看别人的文章还可以使用FileSaver.js插件,欢迎补充