You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js文件下载问题:PDF空白及多格式适配求助

文件下载问题修复指南

问题分析

  • PDF下载后空白:代码中直接用res创建Blob,但axios响应对象的实际文件数据存储在res.data属性里;硬编码type: "application/pdf"可能与服务器返回的实际数据类型不匹配,导致文件损坏。
  • 多格式支持缺失:固定文件名test.pdf无法适配不同文件类型,需要自动识别并保留对应扩展名。

修复步骤

1. 修正Blob创建逻辑

将Blob创建的数据源改为res.data,并从响应头获取正确的Content-Type,替代硬编码值:

downloadFile () {
  api.get(`ips/downloadAttachedFile/` + this.claimId, { responseType: 'blob' }) // 注意此处为小写的blob
    .then(res => {
      // 优先使用服务器返回的Content-Type,兜底用二进制流类型
      const contentType = res.headers['content-type'] || 'application/octet-stream';
      const blob = new Blob([res.data], { type: contentType });
      const downloadUrl = window.URL.createObjectURL(blob);
      // 后续下载逻辑...
    })
}

2. 自动获取文件名与扩展名

通过响应头的Content-Disposition提取服务器返回的文件名;若服务器未返回,则根据Content-Type映射对应扩展名:

downloadFile () {
  api.get(`ips/downloadAttachedFile/` + this.claimId, { responseType: 'blob' })
    .then(res => {
      const contentType = res.headers['content-type'] || 'application/octet-stream';
      const blob = new Blob([res.data], { type: contentType });
      const downloadUrl = window.URL.createObjectURL(blob);
      
      // 初始化默认文件名
      let fileName = 'download';
      // 从Content-Disposition头提取文件名
      const contentDisposition = res.headers['content-disposition'];
      if (contentDisposition) {
        // 兼容filename=xxx和filename*=UTF-8''xxx两种格式
        const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
        if (matches?.[1]) {
          fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
        }
      } else {
        // 无返回文件名时,根据Content-Type映射扩展名
        const extMap = {
          'application/pdf': '.pdf',
          'image/jpeg': '.jpg',
          'image/png': '.png',
          'application/msword': '.doc',
          'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
          'application/vnd.ms-excel': '.xls',
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx'
          // 可按需添加更多文件类型映射
        };
        fileName += extMap[contentType] || '.bin';
      }

      // 创建下载链接并触发下载
      const link = document.createElement('a');
      link.href = downloadUrl;
      link.setAttribute('download', fileName);
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(downloadUrl); // 释放URL对象,避免内存泄漏
    })
    .catch(err => {
      console.error('下载失败:', err);
    })
}

3. 关键注意事项

  • 确保服务器返回正确的Content-Type和Content-Disposition响应头,这是自动识别文件类型和文件名的核心依据。
  • axios的responseType需设置为小写的'blob',部分版本对参数大小写敏感。
  • 释放ObjectURL时,要使用创建时的downloadUrl变量,避免引用错误。

内容的提问来源于stack exchange,提问作者user20042604

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:05:22