跨域下载文件&修改文件名称

引子

前端一般做静态文件下载常用 a 标签进行下载,指定 download 属性,触发下载。

download HTML5
此属性指示浏览器下载 URL 而不是导航到它,因此将提示用户将其保存为本地文件。如果属性有一个值,那么此值将在下载保存过程中作为预填充的文件名(如果用户需要,仍然可以更改文件名)。此属性对允许的值没有限制,但是 / 和 \ 会被转换为下划线。大多数文件系统限制了文件名中的标点符号,故此,浏览器将相应地调整建议的文件名。

注意:
此属性仅适用于同源 URL。
尽管 HTTP URL 需要位于同一源中,但是可以使用 blob: URL 和 data: URL ,以方便用户下载使用 JavaScript 生成的内容(例如使用在线绘图 Web 应用程序创建的照片)。
如果 HTTP 头中的 Content-Disposition 属性赋予了一个不同于此属性的文件名,HTTP 头属性优先于此属性。
如果 HTTP 头属性 Content-Disposition 被设置为inline(即 Content-Disposition=‘inline’),那么 Firefox 优先考虑 HTTP 头 Content-Dispositiondownload 属性。

然而这种方法有一个弊端,在跨域资源的情况下, download 属性会无法工作,重命名下载资源。 那么,如何重命名资源

跨域下载

我们可以新建一个 http 请求,用于下载静态文件资源。

export function downFile(url , filename) {
  axios
    .get(url, {
      responseType: 'blob'  //  注意 responseType 属性需要加上
    })
    .then(async res => {
      console.log(res);
      const data = res.data;
      const bolb = new Blob([data], { type: 'application/pdf' });  // 此处文件类型为pdf
      saveAs(bolb, filename);
    });
}

其中 responseType 字段告诉服务返回 blob 流,我们可以直接用 Blob 对象进行转换。 拿到 blob 对象后就可以进行a 标签下载了

触发下载

function saveAs(blob, filename) {
  let aLink = document.createElement('a');
  let evt = document.createEvent('HTMLEvents');
  evt.initEvent('click', true, true); // initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
  aLink.download = filename;
  aLink.href = window.URL.createObjectURL(blob);
  aLink.click();
}

新建一个 a 标签, 手动触发下载即可。

base64 文件下载

假如服务端进行了接口封装,直接返回了 base64 字符串,进行转化即可

function  downloadFile(content, fileName) {
      let aLink = document.createElement('a');
      let blob = base64ToBlob('data:application/pdf;base64,' + content, 'pdf');
      let evt = document.createEvent('HTMLEvents');
      evt.initEvent('click', true, true);
      aLink.download = fileName;
      aLink.href = URL.createObjectURL(blob);
      aLink.click();
    }
   function  base64ToBlob(base64) {
      return new Promise(resolve => {
        let arr = base64.split(',');
        let mime = arr[0].match(/:(.*?);/)[1];
        let bstr = atob(arr[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        resolve(new Blob([u8arr], { type: mime }));
      });
    }
downloadFile(url, 'filename')

猜你喜欢

转载自blog.csdn.net/weixin_48408736/article/details/120887190
今日推荐