Skip to content
On this page

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);
    }
  }

缺点就是需要先下载到内存,再导出到硬盘,所以需要时间。也就是之前是直接调起浏览器的下载,进度条是浏览器处理,现在需要自己处理下载,自己去做进度条。

Released under the MIT License.