axios下载文件(responseType:‘blob‘),判断是下载成功返回了二进制流还是失败返回了对象(比如服务端拒绝,返回对象,前端如果依然按二进制流处理会导致下载undefined文件)

本文介绍如何在使用axios请求文件下载时,通过配置responseType为'blob',并利用FileReader和JSON.parse处理可能的错误响应,确保正确识别并处理下载失败情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比如前后端约定,下载成功返回二进制流,下载失败返回对象{code: 0, msg: ‘失败原因’}

问题:当下载文件时,axios配置responseType: ‘blob’,此时后台返回的数据会被强制转为blob类型;如果后台返回失败对象,前端也无法得知,如果按正常处理会得到名为undefined的文件。

解决:在try代码块里面尝试将axios已经转成blob格式的res转回json格式,如果不报错说明服务端返回的是对象,表示下载失败;如果进入catch说明返回的是二进制流。

主要技术点:FileReader window.URL.createObjectURL Blob a标签实现下载

axios配置:
axios({
	method: ‘post’,
    baseURL: ‘’,
    url: ‘’l,
    timeout: 3000,
    headers: {},
    data: options.method.toLowerCase() !== 'get' ? options.data : undefined,
    responseType: 'blob'
}).then(
       res => {
          const data = res.data
          // 有可能下载失败,比如返回{code: 0},但设置了responseType: 'blob',axios会把data强制转为blob,导致下载undefined.excel(后缀取决于文件类型,这里只是举例)
          // 解决:将已转为blob类型的data转回json格式,判断是否下载成功
          const r = new FileReader()
          r.onload = function () {
          // 如果JSON.parse(this.result)不报错,说明this.result是json字符串,则可以推测是下载报错情况下返回的对象,类似于{code: 0}
           // 如果JSON.parse(this.result)报错,说明是下载成功,返回的二进制流,则进入catch进行后续处理
           try {
             const resData = JSON.parse(this.result) // this.result为FileReader获取blob数据转换为json后的数据,即后台返回的原始数据
            // 如果执行到这里,说明下载报错了,进行后续处理
           } catch (err) {
            // 下载正常处理
             let fileName = res.headers['content-disposition']
             // 获取文件名
             if (fileName && fileName.length >= 2) {
               fileName = fileName.split('=')[1]
             }
             fileName = decodeURIComponent(fileName)
             // 兼容ie11
             if (window.navigator.msSaveOrOpenBlob) {
               try {
                 const blobObject = new Blob([data])
                 window.navigator.msSaveOrOpenBlob(blobObject, fileName)
               } catch (e) {
                 console.log(e)
               }
               return
             }
             // a标签实现下载
             let url = window.URL.createObjectURL(new Blob([data]))
             let link = document.createElement('a')
             link.style.display = 'none'
             link.href = url
             link.setAttribute('download', fileName)
             document.body.appendChild(link)
             link.click()
             resolve(fileName)
           }
         }
         r.readAsText(data) // FileReader的API
       }).catch(res => {
         console.log(res)
      })
### 解决设置 `responseType` 为 `blob` 返回文件乱码的问题 当在前端通过 Axios 设置 `responseType: 'blob'` 来处理文件下载时,如果返回的内容仍然出现乱码,则可能是由于以下几个方面的原因造成的: #### 1. **Mock 模块的影响** 如果项目中使用了 Mock.js 或类似的工具来模拟后端接口响应,可能会干扰原生 AJAX 请求的行为。即使未对特定的下载接口进行显式的拦截,Mock 的全局行为也可能改变实际返回的数据类型[^2]。因此,在开发环境中应禁用 Mock 对该接口的任何影响。 可以通过以下方式排除 Mock 的干扰: ```javascript // 如果有 mock 配置,需确保不拦截目标接口 if (process.env.NODE_ENV === 'development') { window.mock && window.mock.restore(); // 清除所有已定义的 mock 数据 } ``` #### 2. **确认服务器端 MIME 类型** 服务器端需要正确设置 HTTP 响应头中的 Content-Type 字段,以便客户端能够识别并解析接收到的数据。对于 Excel 文件而言,常见的 MIME 类型为 `application/vnd.ms-excel` 或其他相关标准[^3]。如果没有正确指定此字段,浏览器可能无法理解数据的实际格式从而导致显示异常。 验证服务端是否设置了合适的头部信息可以借助开发者工具网络面板观察具体请求及其对应的 Response Headers 是否包含类似下面这样的条目: ``` Content-Disposition: attachment; filename="example.xlsx" Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet ``` #### 3. **Axios 配置校验** 确保 Axios 实例创建或者调用方法时明确指定了参数选项 `responseType='blob'` 。这一步骤决定了接收器将以二进制大对象的形式读取远程资源而不是默认字符串化处理[^1]。 以下是完整的示例代码片段展示如何发起带有适当配置项的 GET/POST 请求用于获取文件流: ```javascript import axios from 'axios'; const downloadFile = async () => { try { const response = await axios({ method: 'get', url: '/api/download', responseType: 'blob' // 关键点在于这里要声明期望得到的是 Blob 格式的结果 }); // 创建临时链接节点实现自动触发保存动作 const link = document.createElement('a'); link.href = URL.createObjectURL(response.data); link.download = 'filename.ext'; // 自定义导出后的名字扩展名部分依据实际情况调整 link.click(); } catch(error){ console.error("Error occurred while downloading file", error); } }; ``` 另外值得注意的一点是某些情况下还需要额外关注编码问题比如 UTF-8 BOM 等因素也有可能间接引发看似无规律可循的现象所以最好能进一步深入分析整个传输链路各个环节是否存在潜在隐患。 --- ### 总结建议 综上所述,为了有效规避因不当设定而导致最终呈现效果不佳的情况发生可以从上述三个方面逐一排查定位根本原因所在进而采取针对性措施加以改进优化直至达到预期目的为止。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值