平时在前端下载文件有两种方式,一种是后台提供一个 URL 下载,需要先转换成二进制文件流再下载,另一种就是后台直接返回文件的二进制内容,然后前端转化一下再下载。
1.后端提供url前端下载
如果是excel、word等文件,直接通过window.open(url地址) 方法直接下载。pdf可以直接预览
如果是图片格式,可以通过window.open(url地址)来进行预览,下载需要通过以下方式:
//首先封装下面的方法
const downloadByBlob = (url, name) => {
let image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.src = url;
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob(blob => {
let url = URL.createObjectURL(blob);
download(url, name); //vue2前面不要忘记加个this
// 用完释放URL对象
URL.revokeObjectURL(url);
});
};
}
const download = (href, name) => {
let eleLink = document.createElement("a");
eleLink.download = name;
eleLink.href = href;
eleLink.click();
eleLink.remove();
}
//调用方法
const textclick = () => {
//调后端的接口拿到的url地址,已省略请求
let url = 'http://mewyeah.pz-smart.cn/profile/upload/20230325182100_aaa_54aae6d57d3e48ec93748b82c8ff3b6a.jpg'
downloadByBlob(url, 'aa.jpg') //传入地址和图片名称
}
2.转换成二进制文件流下载
如果是pdf格式的文件,需要下载, 需要后端提供pdf流才可下载
//调接口
export const downloadApi=(url)=> {
return request({
url: `/file/download`,
method: 'get',
responseType: 'arraybuffer', // 必须写这行
params:{url}
})
}
//封装一个方法
const download = (res, filename) => {
// 创建blob对象,解析流数据
const blob = new Blob([res]);
const a = document.createElement("a");
// 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
const URL = window.URL || window.webkitURL;
// 根据解析后的blob对象创建URL 对象
const herf = URL.createObjectURL(blob);
// 下载链接
a.href = herf;
// 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// 在内存中移除URL 对象
window.URL.revokeObjectURL(herf);
};
//合适的位置调用
const textclick = async () => {
let url="/profile/upload/77126a94dfe99ad9c0a5a8f2fc9.pdf"
let res=await downloadApi(url)
download(res, 'aaa.pdf'); //传入url和文件名称
}