方法一: a标签直接通过链接地址下载
正常情况下,通过window.location = url就可以下载文件。浏览器判断这个链接是一个资源而不是页面的时候,就会自动下载文件。
但是通过文件流生成的url对应的资源是没有文件名的,需要添加文件名。这个时候就可以用到a标签,a标签我们经常会用到href属性,但是其实还有一个download属性,这个属性就指定了下载的文件名,代码如下:
let a = document.createElement('a');
a.href = objectUrl; // 文件流生成的url
a.download = fileName; // 文件名
document.body.appendChild(a);
a.click();
a.remove();
方法二:二进制流接收文件
获取数据需要在请求的时候设置responseType: 'blob'
。
拿到文件流之后,需要生成一个URL才可以下载。
可以通过URL.createObjectURL()
方法生成一个链接,代码如下:
download() {
this.http.get('/media/api/storage/download?path=' + this.showMedia.mediaPath + this.showMedia.mediaName,{responseType:'blob'}).subscribe(data =>{
const link = document.createElement('a');
const blob = new Blob([data]);
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
link.setAttribute('download', `${this.showMedia.mediaName}`);
document.body.appendChild(link);
link.click()
document.body.removeChild(link);
});
}
什么是Blob呢,MDN官方解释:Blob 对象表示一个不可变、原始数据的类文件对象。Blob
表示的不一定是JavaScript原生格式的数据(https://developer.mozilla.org/zh-CN/docs/Web/API/Blob)
后端传过来的文件流存储在内存中,然后生成的URL就是文件流在内存中的地址,当然这个地址是临时的,浏览器在 document 卸载的时候,会自动释放它们。MDN官方建议,当不再需要这些URL对象的时候,应该调用URL.revokeObjectURL()主动释放。
https://segmentfault.com/a/1190000023077368
https://www.cnblogs.com/woai3c/p/11262491.html