2022-07-自定义下载文件名
1. 需求场景
后端会生成一些下载文件放到oss上,然后前端提供下载链接,用户点击下载,前端用浏览器的open方法打开链接地址,调起浏览器的下载功能进行下载。 但是有时候需要改文件名,比如落地到oss上的文件名是个id名称,或者是uuid名称,用户下载下来,看不懂,就需要前端转一手,改文件名。
不改文件名的下载方式
jsx
window.open(fileUrl)
2. 解决方式一:a标签的download属性
jsx
down = (url: string) => {
// window.open(url);
const downloadLink = document.createElement('a');
// downloadLink.download = '重命名.mp4';
downloadLink.setAttribute(
'download',
"重命名.mp4"
);
downloadLink.href = new URL(url);
downloadLink.click();
}
由于oss的地址和我们项目的地址肯定不是一个域名,而download只支持同源域名下载。无论oss域名是否支持跨域,download是只支持同源改名。 所以这个方案不适合我们。
3. 解决方式二:用blob转一手
jsx
// 视频下载
down = (url: string) => {
// window.open(url);
this.getBlob(url, (blob) => {
this.saveAs(blob, '重命名.mp4');
});
}
getBlob = (url: any, cb: any) => {
console.log('开始下载', moment().format('mm:ss'));
this.setState({ loading: true });
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
cb(xhr.response);
console.log('下载完成', moment().format('mm:ss'));
this.setState({ loading: false });
}
};
xhr.send();
}
// 保存
// @param {Blob} blob
// @param {String} filename 想要保存的文件名称
saveAs = (blob: any, filename: any) => {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename);
} else {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
window.URL.revokeObjectURL(link.href);
}
}
缺点就是需要先下载到内存,再导出到硬盘,所以需要时间。也就是之前是直接调起浏览器的下载,进度条是浏览器处理,现在需要自己处理下载,自己去做进度条。