前端js-->文件流转文件下载

1,524 阅读1分钟

我正在参加「掘金·启航计划」

问题

下载文件时后端返回值是文件流(一堆乱码),如下图;

image.png 这种情况一般都是让后端改下返回方式,直接以文件方式返回就好了, 我是自己处理的(下面的第二种方法),中间呢会遇到一个大坑,下载的文件打不开,解决方法是设置responseType,下面是具体实现方法;

两种实现方法:

  1. 直接使用window.location.href='下载文件的url'
function downloadDoc() {
  window.location.href = `/api/file/download?id=${row.tplFileId}`
}
  1. 使用Blob对象,下面都是此方法的实现过程,(此方法有个缺点-->只能前端自己指定文件名及文件后缀名)

重点:

  • 一定要设置responseTyperesponseType = 'blob'
  • 把文件流转成Blob对象,
  • 动态创建a标签,使用createObjectURL方法获取href地址
  • 通过自动点击a标签进行下载文件

代码实现

  1. 在请求拦截器中设置responseType
request.interceptors.request.use(config => {
  config.data = config.data || {}
  if (config.method === 'get') {
    if (config.url?.includes('/file/download')) {
      config.responseType = 'blob'
    }
  }
  return config
})
  1. 文件流转文件
// content为后端返回的文件流,
// filename为文件名--自己定义
function downloadFile(content, filename) {
  var el = document.createElement('a');
  // 需要指定文件的后缀名
  el.download = filename+'.docx';
  el.style.display = 'none';
  // type作用也可以指定后缀名,没上面那个优先级高
  var blob = new Blob([content], { type: 'application/msword' });
  el.href = URL.createObjectURL(blob);
  // 自动点击元素
  document.body.appendChild(el);
  el.click();
  // 移除元素
  document.body.removeChild(el);
};

记录application文件类型:

{type: 'application/msword' } //文档.doc
{type: 'application/vnd.ms-excel' } //表格.xls
{type: 'application/vnd.ms-powerpoint' } //ppt.ppt
{type: 'application/pdf' } //pdf.pdf

iframe预览文件流

<iframe :src='data.srcFile' style="height: 100%;width: 100%"></iframe>
const data = reactive({
  srcFile: '',
})
function previewFile(fileId) {
  getFileDownload({
    query: {
      id: fileId,
    }
  }).then(res => {
    if (!res) return false;
    // 设置type,否则iframe会下载改文件
    var blob = new Blob([res],{
      type: 'application/pdf;charset=utf-8'
    });
    data.srcFile = URL.createObjectURL(blob);
  })
}