后端返回文件流,前端如何下载

如何在前端实现Excel文件下载:Blob处理与文件名解码详解

在前端开发中,文件下载是一个常见需求,尤其是在导出Excel数据报表的场景。本文将详细介绍如何使用Blob对象处理二进制流数据并正确解码中文文件名,以解决常见的乱码问题。

核心代码实现

// 省略了代码中的具体业务逻辑,主要突出关键的Blob处理和文件名解码部分

function exportExcel() {
  // 设置请求参数...
  
  mallapiOrderinfoDownFile(params, { responseType: 'blob' })
    .then(response => {
      const blob = new Blob([response.data], { 
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
      });
      
      const downloadUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;

      const fileName = decodeURIComponent(
        response.headers['content-disposition']?.split('filename=')[1] || '默认文件名.xlsx'
      );

      link.setAttribute('download', fileName);
      document.body.appendChild(link);
      link.click();
      
      window.URL.revokeObjectURL(downloadUrl);
      document.body.removeChild(link);
    })
    .catch(error => {
      console.error('导出失败:', error);
      proxy.$message.error("导出失败");
    });
}

关键技术点解析

1. responseType: 'blob'的作用

设置responseType: 'blob'可确保获取到的是二进制流数据,适用于文件下载场景,其中也必须要写入,其可以通过设置一个XMLHttpRequest对象的 responseType属性来改变一个从服务器上返回的响应的数据类型,当时没有规定responseType类型导致下载后的文件出现了乱码的情况 。

2. Blob对象与MIME类型

创建Blob对象时,需指定正确的MIME类型,以确保浏览器能正确解析文件内容,以下是一些常见的MIME类型及其用途:

文本文件:    
    text/plain: 纯文本文件
    text/html: HTML 文件
    text/css: CSS 样式表
    text/javascript: JavaScript 文件
图像文件:
    image/jpeg: JPEG 图像文件
    image/png: PNG 图像文件
    image/gif: GIF 图像文件
    image/svg+xml: SVG 图像文件
音频文件:
    audio/mpeg: MP3 音频文件
    audio/ogg: Ogg 音频文件
    audio/wav: WAV 音频文件
视频文件:
    video/mp4: MP4 视频文件
    video/webm: WebM 视频文件
    video/ogg: Ogg 视频文件
应用文件:
    application/pdf: PDF 文件
    application/zip: ZIP 压缩文件
    application/json: JSON 数据
    application/xml: XML 数据
    application/octet-stream: 二进制流数据(通常用于下载任意类型的文件)
Microsoft Office 文件:
    application/vnd.ms-excel: Excel 文件(.xls)
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: Excel 文件(.xlsx)
    application/msword: Word 文件(.doc)
    application/vnd.openxmlformats-officedocument.wordprocessingml.document: Word 文件(.docx)
    application/vnd.ms-powerpoint: PowerPoint 文件(.ppt)
    application/vnd.openxmlformats-officedocument.presentationml.presentation: PowerPoint 文件
其他文件类型:
    application/font-woff: WOFF 字体文件
    application/font-sfnt: TrueType 字体文件
    application/x-shockwave-flash: Flash 文件

3. 中文文件名解码处理

代码中的【fileName】:指的是我们在下载文件的时候名称取得是什么,其中用到了decodeURIComponent因为他是将返回的解析为字符集,其中解码的方法一般有decodeURI()和decodeURIComponent(),其中 decodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问号和井字号;而 decodeURIComponent 则会对它发现的任何非标准字符进行编码,所以一般我们去使用encodeURIComponent去进行解码,通过解码Content-Disposition头中的文件名,可以正确显示包含中文字符的文件名。

完整实现流程

  1. 发起请求,设置responseType: 'blob'获取二进制流数据。
  2. 创建Blob对象并指定合适的MIME类型。
  3. 生成下载链接,并解码文件名以处理中文乱码。
  4. 模拟点击下载链接,完成文件下载过程。
  5. 清理资源,避免内存泄漏。

常见问题解决方案

1: 文件损坏或无法打开

  • 检查是否设置了responseType: 'blob'
  • 确保指定了正确的MIME类型。
  • 验证后端返回的文件流是否有效。

2: 文件名乱码显示问题

  • 确认服务器设置了正确的Content-Disposition头。
  • 检查解码逻辑,确保正确处理中文文件名。
  • 可能需要处理双重编码情况。

3: 文件在浏览器中打开而非下载

  • 确保设置了下载属性(download)。
  • 检查MIME类型是否被浏览器识别为可展示类型。

最佳实践建议

  1. 统一使用UTF-8编码。
  2. 添加完善的错误处理和用户提示。
  3. 在处理大文件下载时显示下载进度。
  4. 验证文件类型,避免XSS攻击。

通过本文介绍的方法,可以有效处理文件下载中的相关问题,包括解决中文文件名乱码等。关注三个关键点:responseType: 'blob'、正确的MIME类型、解码URL编码的文件名。


希望这篇文章能帮助你解决文件下载中的各种问题!如果还有疑问,欢迎在评论区留言讨论(本人第一次发表文章如有写的不好的地方请指正。)。

### 前端接收后端文件流并实现自动下载 为了实现在前端接收到由后端返回文件流并触发浏览器自动下载该文件的功能,可以采用基于 `axios` 发起 HTTP 请求的方式获取文件流,并利用 JavaScript 的 `Blob` API 创建文件对象。之后借助 `<a>` 标签模拟点击事件完成文件下载操作。 下面是一个完整的 Vue.js 方法用于发起请求以及处理响应中的文件流: ```javascript async function downloadFile() { try { const response = await axios({ method: 'get', url: '/api/download', // 后端文件流的API路径 responseType: 'blob' // 显式指定期望得到的是二进制大对象(BLOB) }); // 获取文件名可以从header中读取content-disposition字段解析出来, // 或者直接定义一个默认名称。 let filename = "default_filename"; const contentDisposition = response.headers['content-disposition']; if (contentDisposition) { const matches = /filename=([^;]+)/.exec(contentDisposition); if (matches != null && matches[1]) { filename = decodeURIComponent(matches[1].trim()); } } // 构建URL对象<a>标签使用 const blob = new Blob([response.data]); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; // 将链接添加至DOM树以便触发click() document.body.appendChild(link); // 执行点击动作启动下载流程 link.click(); // 清理临时创建的对象防止内存泄漏 window.URL.revokeObjectURL(link.href); document.body.removeChild(link); } catch (err) { console.error(err.message || err); } } ``` 此方法适用于大多数场景下的文件下载需求,无论是文档还是图片等其他类型的文件都可按照上述逻辑进行适配调整[^1]。 对于特定 MIME 类型的支持,比如 Excel 文件,则需确保设置正确的 Content-Type 头部信息给 `Blob` 构造器,例如 `"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"` 表示 `.xlsx` 文件格式[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值