vue axios 请求二进制流excel文件,response乱码

图片描述问题:当axios发起post请求,后端返回的是二进制流excel文件,前台获取response时出现乱码问题,求解决方法

图片描述
response返回乱码数据。

 downloadModel(){
        // window.location.href = window.open(axios.defaults.baseURL +'/aaa/template');
        // let downLoadModel = window.open();

        // let fileDownload = require('js-file-download');
        this.$post('aaa/template',{params:null},{responseType: 'arraybuffer'}).then(res => {
        // this.$get('/aaa/template').then(res => {
          console.log(res);
          // let fileName = res.headers['content-disposition'].match(/fushun(\S*)xls/)[0];
          // fileDownload(res,fileName);

          let blob = new Blob([res], {type: "application/vnd.ms-excel;charset=utf-8"});

          // let objectUrl = URL.createObjectURL(blob);
          // window.location.href = objectUrl;

          var link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = "对账模板";
          link.click();

        }).catch((e) => {
          this.$message.warning('下载失败');
          console.log(e);
        })
      },

图片描述

强行text打开还是乱码

阅读 22.4k
7 个回答

最后一次更新:

既然楼主采纳了我的答案,但有些问题,我还是要仔细说说,为此我写了如下一段代码,为了方便,我是直接下载一个存在在服务器根目录下的xls。

axios.get('http://127.0.0.1/1.XLS', {
                responseType: 'blob' //指定返回数据的格式为blob
            })
            .then(response => {
                console.log(response);//把response打出来,看下图
                let url = window.URL.createObjectURL(response.data);
                console.log(url)
                var a = document.createElement("a");
                document.body.appendChild(a);
                a.href = url;
                        a.download = '2.xls';
                        a.click();
                        window.URL.revokeObjectURL(url);
            })
            .catch(err => {
                console.log(`接口调用失败`);
               
                console.log(err);
            })

图片描述
这个图可以明显的看到,返回的response在的data 是一个blob Object

createObjectURL 函数,接受的参数是blob 类型或者是File 类型

所以说,我想创建的URL 对象只需要 如下代码

 let url = window.URL.createObjectURL(response.data);

因为response.data 已经是一个blob Object 了,完全不需要再像楼主在评论在回复我的解决方案中哪样,用 let url = window.URL.createObjectURL(new Blob([res.data]))载入,哪为什么 这样的代码解决了楼主的问题呢,

个人猜想原因:
1.最有可能的原因,楼主请求的服务端,强制返回的就是二进制流,也就是说 responseType: 'blob' 根本没有作用,因为设置responseType也需要服务端兼容的,并不是你指定什么,服务端就一定会按照你的指定来返加
2.楼主在axios设置了拦截器,修改了返回数据,但这个可能性应该不大

楼主修改问题后第一次编辑如下:

楼主用文本编辑器打开一个Excel,然后告诉我们这个是乱码,这题当我没有答过,其实看文件头明显可以看出来,这已经是一个Excel文件了

原回答如下:
responseType: 'arraybuffer' 改成 responseType: 'blob'

let objectUrl = URL.createObjectURL(res.data);

response乱码不是很正常吗?你强行用text打开一下你的excel看看是不是乱码?你看下载文件就行了,不用管response的文本输出。

这个乱码应该是后端设置的编码问题

responseType: 'blob' blob 设置这个类型呢? {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"} ,还有 别用编辑打开excel啊

我这边postman下载也没问题,但浏览器下载也是乱码...

axios.post(axios.defaults.baseURL+'/aaa/template', {params:null},{responseType: 'blob'})
      .then(function (res) {
        if(!res.data){
          return
        }
        let url = window.URL.createObjectURL(new Blob([res.data]))
        let link = document.createElement('a')
        link.style.display ='none'
        link.href = url
        link.setAttribute('download','excel.xls')
        document.body.appendChild(link)
        link.click();
      })
      .catch(function (error) {
        console.log(error);
      });

我们项目里面也遇到了,找了很久找到原因,是mockjs引起的require('mockjs')
mock把请求返回结果类型给修改了
image
下面是去掉mockjs后的返回结果,请求看1楼
image

结果发现,
1.谷歌浏览器下载,office打不开。
2.QQ浏览器谷歌内核下载,postman下载,office打开提示修复,点击确定,正常显示数据。
3.谷歌浏览器下载,wps正常打开,也没有修复提示。

经过分析,是后台返回的数据流里面带有接口请求状态等信息,让后台去掉后就正常了。
image

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题