axios下载接口后端返回了json但前端得到的是blob

本文介绍了如何在axios请求中处理后端返回JSON而非预期的Blob,通过响应拦截器实现数据类型转换,确保文件下载或错误提示的正确性。

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

背景:

        通过axios下载文件,正常情况下后端返回内容blob,前端接收并导出文件。但有时候,后端业务逻辑需要提示错误,于是返回json,但前端预期接收的是blob,所以导出去的文件内容是json字符串。

原因:

        axios请求头配置了响应格式 responseType: 'blob'

const service = axios.create({
    baseURL: '/'
})
// 导出用户列表
export function exportUserList(data){
  return request({
    url: '/admin/accelerate/duration/download',
    method: 'post',
    responseType: 'blob', // 指定响应内容为blob
    data
  })
}

解决方法:

        在axios响应拦截器中,判断请求的响应类型。若预期返回blob但实际返回json,则将blob转成json字符串,然后进行错误提示。

// blob转字符串
export const blobTojsonstr = (blob) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => resolve(e.target.result);
    reader.onerror = (e) => reject(e.target.error);
    reader.readAsText(blob);
  });
}
import { Notification } from 'element-ui'

// HTTP response 拦截
service.interceptors.response.use(
  async (res) => {
    const status = res.status
    const responseType = res.config.responseType // 预期响应数据类型
    const contentType = res.headers['content-type'] // 真实响应数据类型

    let resData = null,
      isBlob = ['arraybuffer', 'blob'].includes(responseType)
    if (!isBlob) {
      // 预期是非文件,即json
      resData = res.data
    } else {
      // 预期是文件
      if (contentType.indexOf('application/json') > -1) {
        // 下载接口异常:Blob转Json后解密
        isBlob = false
        try {
          const content = await blobTojsonstr(res.data)
          resData = JSON.parse(JSON.parse(content).data)
        } catch (error) {
          resData = res.data
        }
      } else {
        resData = res.data
      }
    }

    // 不正确的状态码进行统一处理
    if (!isBlob && (status !== 200 || resData.code !== 0)) {
      const errMsg = resData.msg
      Notification.error({
        title: errMsg
      })

      return Promise.reject(new Error(errMsg))
    }

    return resData
  },
  (error) => {
    return Promise.reject(new Error(error))
  }
)

效果:

        正常情况下,后端返回blob,axios接收blob并导出文件。

        异常情况下,后端返回json,axios接收blob后转成json,根据错误码code提示错误。

<think>嗯,用户想了解如何使用后端的FastExcel库导出Excel文件,然后前端Axios处理这个返回的Excel。首先,我需要确认FastExcel在Java中的使用方式,可能用户指的是某个特定的库,比如FastExcel或者可能是Apache POI的某个封装?不过通常在后端Java中生成Excel常用的是Apache POI或者Alibaba的EasyExcel。不过用户明确提到FastExcel,可能是指某个特定的库,比如https://github.com/dhatim/fastexcel,这个库确实存在,用于高效生成Excel文件。 接下来,用户需要前端Axios处理返回的Excel。这里的关键点是后端如何设置响应头,让浏览器知道返回的是一个可下载的文件,以及前端如何正确处理二进制流并触发下载。 首先,后端部分需要设置正确的Content-Type,比如application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,以及Content-Disposition为附件,指定文件名。然后,将生成的Excel文件写入响应输出流。 前端部分,使用Axios发起请求时,需要指定responseType为'blob',以确保正确处理二进制数据。接收到响应后,需要将Blob数据转换为下载链接,通过创建a标签并模拟点击来实现下载。同时,可能需要检查文件名,如果后端在Content-Disposition中提供了文件名,可以用正则提取,否则可能需要使用其他方式。 需要注意的是,可能存在的错误点包括:后端没有正确设置响应头,导致前端无法识别为文件下载前端未设置responseType为blob,导致数据解析错误;生成URL对象后没有释放内存,需要使用revokeObjectURL来清理。 另外,可能需要处理错误情况,比如后端生成Excel时出现异常,这时应该返回适当的HTTP状态码,前端需要捕获错误并提示用户。 现在需要将这些步骤转化为代码示例。后端使用FastExcel生成Excel并设置响应头,前端使用Axios获取数据并触发下载。需要确认代码的正确性,比如Java后端的Controller方法是否正确处理请求,以及前端下载逻辑是否兼容不同浏览器。 可能的疑问点:是否所有浏览器都支持通过URL.createObjectURL和a标签下载?是的,现代浏览器都支持。是否需要处理兼容性问题?可能不需要,如果用户使用的是现代浏览器的话。 总结步骤: 1. 后端生成Excel并设置正确的响应头。 2. 前端使用Axios请求,设置responseType为'blob'。 3. 前端返回Blob转换为URL,创建a标签触发下载。 4. 清理生成的URL对象。</think>以下分为后端(Java + FastExcel)和前端Axios)的实现示例: --- ### 后端代码(Java + FastExcel) ```java import org.dhatim.fastexcel.Workbook; import org.dhatim.fastexcel.Worksheet; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @GetMapping("/export-excel") public void exportExcel(HttpServletResponse response) throws IOException { // 设置响应头(关键!告诉浏览器这是文件下载) response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=export.xlsx"); // 使用 FastExcel 生成 Excel try (Workbook workbook = new Workbook(response.getOutputStream(), "MyApp", "1.0")) { Worksheet sheet = workbook.newWorksheet("Sheet1"); // 写入数据(示例:A1 单元格) sheet.value(0, 0, "Hello"); sheet.value(0, 1, "World"); workbook.finish(); } } ``` --- ### 前端代码(Vue + Axios) ```javascript axios({ method: 'get', url: '/export-excel', responseType: 'blob' // 关键!告诉 Axios 处理二进制流 }) .then(response => { // 创建 Blob 对象表示文件内容 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; link.setAttribute('download', 'export.xlsx'); // 设置下载文件名 document.body.appendChild(link); link.click(); // 清理临时对象 link.remove(); window.URL.revokeObjectURL(downloadUrl); }) .catch(error => { console.error('下载失败:', error); }); ``` --- ### 关键点说明 1. **后端必须设置响应头** `Content-Type` 和 `Content-Disposition` 告诉浏览器这是需要下载的 Excel 文件。 2. **前端指定 `responseType: 'blob'`** Axios 默认期望 JSON 文本,需明确指定处理二进制数据。 3. **使用 Blob + 虚拟链接下载** 将二进制数据转换为浏览器可识别的文件链接,通过模拟点击实现下载。 4. **文件名处理** 如果后端动态生成文件名,可通过解析 `response.headers['content-disposition']` 提取文件名。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值