前端下载文件之 blob 处理文件流

612 阅读1分钟

直接上 Vue 代码

// 获取后端直接返回的文件流
getBlob(id) {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest();
    //按业务配置,填自己的baseURL
    xhr.open('POST', this.baseURL + `/oms/summary/downloadPDF/${id}`, true);
    xhr.setRequestHeader('x-token', sessionStorage.getItem('x-token'));
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    // 检查下面这一步不能少
    xhr.responseType = 'blob';
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response);
      }
    };
    xhr.send();
  });
},
  //下载文件操作
  downloadPDF(id, filename) {
    this.getBlob(id).then((res) => {
      // 在这里可以设置下载文件格式
      let blob = new Blob([res], { type: 'application/pdf' });
      if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveBlob(blob, filename);
      } else {
        let link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = filename;
        link.click();
        window.URL.revokeObjectURL(link.href);
      }
    });
  },

--可有可无的小故事--
之前项目中同事有写过类似的下载文件,当时项目是基于react的,看了下代码找到专门处理下载的一个js文件,把它挪过来改了改,能跑了,然而!
下载的是个json文件,一看果然是报错了,报了500,后端同学一看,说我忘带token了。
行嘛,加上token继续跑,下载框框一弹,很激动,但仔细一看怎么格式是xml?手动改成pdf可以正常下载,那应该是没定义好下载文件格式!
于是又是上网一顿搜,一顿找在代码哪个地方加我的格式定义,结果苦苦找了好久都对不上那看着很高深的代码。后来竟是在知乎上找到一个非常简洁的解决方法,我终于决定抛弃冗长的旧代码来试试 。试了一下,没反应,还好答主提醒没有responseType = 'blob'不行,最终结合旧代码再一改,终于成了!感天动地!!
后来反思为什么之前找不到加文件格式的地方,是因为返回来的blob被直接丢去msSaveBlob处理了,没有定义出来quq
let blob = new Blob([res], { type: 'application/pdf' });