使用axios下载后端返回的文件流,并能够提示后端报错信息

这里与后端已经约定好了,成功有文件流时返回staus为0

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

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

具体代码如下(这里的提示使用的是elementUI提供的message,下载的文件是压缩包文件,也可以根据需求修改文件类型):

// 点击下载事件
        async downloadFile() {var that = this;
            axios({
                method: 'post',
                url: '',
                data: this.searchForm,
                responseType: 'blob',
            })
                .then((res) => {
                    const data = res.data;
                    // 有可能下载失败,比如返回{status: 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字符串,则可以推测是下载报错情况下返回的对象,类似于{status: 0}
                        // 如果JSON.parse(this.result)报错,说明是下载成功,返回的二进制流,则进入catch进行后续处理
                        try {
                            const resData = JSON.parse(this.result); // this.result为FileReader获取blob数据转换为json后的数据,即后台返回的原始数据
                            // 如果执行到这里,说明下载报错了,进行后续处理
                            if(resData.status !== 0) {
                                that.$message({
                                    message: resData.statusText,
                                    type: 'warning',
                                });
                            }
                        } catch (err) {
                            // 下载正常处理
                            that.$message({
                                message: '文件下载中',
                                type: 'success',
                            });
                            let blob = new Blob([res.data], { type: 'application/zip' }); //如果文件是excel,把type换成 type: 'application/vnd.ms-excel' 即可

                            let url = window.URL.createObjectURL(blob);
                            const link = document.createElement('a'); // 创建a标签
                            link.href = url;
                            link.download = '文件名'; // 重命名文件
                            link.click();
                            URL.revokeObjectURL(url); // 释放内存
                        }
                    };
                    r.readAsText(data); // FileReader的API
                })
                .catch((res) => {
                    console.log(res);
                    that.$message.error('下载失败');
                });
        },

这样就可以啦!

posted @ 2020-09-29 15:14  猛猛滴超人  阅读(2202)  评论(1编辑  收藏  举报