0


前端下载文件流,解决设置返回值类型responseType:‘blob‘无效的问题

基本流程:前端发起请求设置响应体-后端接收返回文件流-转换为Blob格式文件-前端接收数据

我的实现代码如下:

config.js

import axios from 'axios';
import { getAuthorization } from '@/utils/loginUtils';

// 创建axios实例
const Service = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL, // 设置请求的基本URL
    // 定义统一的请求头
    headers: {
       'Authorization': getAuthorization(), // 用于在请求中传递身份验证凭据,通常用于进行用户身份验证
    },
    // 配置请求超时时间
    timeout: 60000
});

request.js

import Service from "./config";

// 封装get请求
export const get = (config) => {
    return Service({
        ...config,
        method: 'get',
        data: config.data,
        responseType: config.responseType
    });
};

// 封装post请求
export const post = (config) => {
    return Service({
        ...config,
        method: 'post',
        data: config.data
    });
};

index.js

(重点设置:responseType: 'blob')

import { post,get } from './request';

// 指标导出接口
const exportRfidIndicator = () => {
    return get({
        url: process.env.VUE_APP_BASE_API+'/api/rfid/exportRfidIndicator',
        responseType: 'blob' // 设置响应类型为'blob'返回的是一个包含二进制数据的 Blob 对象
    })
}

export default {
    exportRfidIndicator
}

页面文件关键代码:

<div class="download_file" @click="DownloadFile"></div>

import api from "@/api/index.js";
export default {
    data() {
        return {
            filename: "后勤资源监控指标.xlsx",
        }
    }
}

methods:{
    // 指标导出
    DownloadFile() {
      api.exportRfidIndicator()
      .then(res => {
        console.log("res",res);
        if(!res) return
        const blob = new Blob([res],{type:'application/vnd.ms-excel'}) // 构造一个blob对象来处理数据,并设置文件类型
        console.log("blob",blob);
        if (window.navigator.msSaveOrOpenBlob) { //兼容IE10
            navigator.msSaveBlob(blob, this.filename)
        } else {
            const href = URL.createObjectURL(blob) //创建新的URL表示指定的blob对象
            console.log("href",href);
            const a = document.createElement('a') //创建a标签
            a.style.display = 'none'
            a.href = href // 指定下载链接
            a.download = this.filename //指定下载文件名
            a.click() //触发下载
            URL.revokeObjectURL(a.href) //释放URL对象
        }
        // 这里也可以不创建a链接,直接window.open(href)也能下载
      })
      .catch(err => {
          console.log(err)
      })
    }
}
 

以上步骤看起来没有一点问题,但是我在自测的时候,直接炸裂,文件直接是打不开

尝试修复也没有用

然后我去看控制台的输出,结果发现不对劲,经过转换应该返回正常的blob格式才对,现在却是如下这种乱码的格式:

因为这里的问题,所以导致下载下来的是一个无效的文件。

然后我就开始进一步的排查,我看了config的rensponseType是“blob”,这说明我配置的responseType: 'blob'生效了,然后所有关于导出的代码都被我看烂了,也没看出来哪里会不对劲,各种百度也都找了,各种博客都找烂了(大概找了上百条),就是没有发现我的代码有什么问题,也没有我这种问题的解决办法。

最后可以说也是缘分,误打误撞的让我看到有个博主的文章,真的起到了关键性的作用,文章其中有一句话:“mock模块会影响原生的ajax请求,使得服务器返回的blob类型变成乱码”,我突然醒悟,因为我在项目开发前期的确是用到了mock,打开控制台发现,mockjs初始化的时候给拦截响应设置了responseType:'',证据如下:

我回到代码中把引用mock的代码注释掉就可以了。真的是怎么也没有想到是mock模块影响了,可让我又学会了一招,以后也可以少走一条弯路了,真实功夫不负有心人!

下面是正常后拿到的数据格式:

最后我也是成功的解决了这个困扰我一天的难题,希望这篇文章可以帮助到更多的人,让人们少走弯路。

标签: 前端 vue

本文转载自: https://blog.csdn.net/qq_52700250/article/details/139354057
版权归原作者 YG·玉方 所有, 如有侵权,请联系我们删除。

“前端下载文件流,解决设置返回值类型responseType:‘blob‘无效的问题”的评论:

还没有评论