Vue系列6 - Vue+axios实现文件下载

文件下载:文件下载通常有几种方法
1.通过url下载
2.location.href
3.form提交直接下载
4.HTML5 a.download结合blob对象进行下载


第一种方式:
第一种方法是前后端的接口只给了一个API请求:
前端第一个实现是使用a标签,

 

第二种方式
这个方法是直接把 DataURLs 或者 BlogURLs 传到浏览器地址中触发下载。有两种方式:

window.location.href = urls; // 本窗口打开下载
window.open(urls, '_blank'); // 新开窗口下载

    // window.location.href = url+ m.sendcode+"?ids="+ idss+"&type="+type;

此请求有个文件稍大就下载不下来了


第三种:
标签的download是HTML5标准新增的属性,作用是指示浏览器下载URL而不是导航到URL,因此将提示用户将其保存为本地文件。
这种是定义的接口不是下载文件的路径,而是通过API可以获得文件的内容,由前端把内容写入到文件中,这种方法是通过获取文件信息,在网页上利用click事件,创建一个文件,然后将文件信息写入到文件中,然后保存

 this.content = content
      this.filename = filename
      const blob = new Blob([this.content])
      if (window.navigator.msSaveOrOpenBlob) {
        // 兼容IE10
        navigator.msSaveBlob(blob, this.filename)
      } else {
        //  chrome/firefox
        let link= document.createElement('a')
        link.download = this.filename
        link.href = URL.createObjectURL(blob)
        link.click()
        URL.revokeObjectURL(link.href)
      }

第四种form表单
不需要我们处理返回二进制流直接下载,非常方便
form的action设置为接口地址,method设置为post,Post到后台的数据设置为input的属性 name = key,value = value的形式,如果有多个key、value的值要传递,那么就设置多个input来分别储存单个的key、value;
如果请求的接口可以不需要参数,那么input还是必须要一个,如果不要得话 会引起接口报错
原理:form的action相当于一个浏览器本页签/页面的一个请求,不会被后台,前台的路由拦截。所以能够提交成功。

注意点:如果设置method为get,在action中的uri添加了参数的话,想用这个参数替代input的key、value形式来提交到后台,这参数是没有效果的,后台拿不到这些参数,真正的参数还是以input的name、value的形式储存,在submit方法执行后传递到后台。
这样我们就是实现了文件下载,但是表单提交的数据一般是简单的键值对,如果传参比较复杂可以考虑将表单序列化提交。

因为项目是基于vue的,而且提交的请求参数涉及很多参数,比较复杂,所以采用了方法三来实现

功能:点击导出按钮,提交请求,下载zip压缩包文件;

第一步:跟后端交付的接口的response header设置了

response.setContentType("application/octet-stream");// 指明response的返回对象是文件流
response.setHeader("Content-Disposition", "attachment; filename="+type+"_"+code+".zip");
response.setCharacterEncoding("UTF-8");

以及返回了文件流。

第二步:修改axios请求的responseType为blob,以post请求为例:

复制代码

axios({
    method: 'post',
    url: url,
    data: {
        参数1: '值',
        参数2: '值',
    },
    responseType: 'blob'
}).then(response => {
    this.download(response)
}).catch((error) => {

})

第三步:请求成功,拿到response后,调用download函数(创建a标签,设置download属性,插入到文档中并click)

methods: {
    // 下载文件
    download (data) {
        if (!data) {
            return
        }
        let url = window.URL.createObjectURL(new Blob([data]))
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        link.setAttribute('download', 'excel.xlsx')

        document.body.appendChild(link)
        link.click()
    }
}

 以下是整个请求的全部代码

                m.loading = true;
                m.$axios.post(url,
                    {
                        searchkey: m.search,
                        countycode: m.lpsword,
                        clasid:m.ltype,
                        usource:m.lpsource,
                        type:type
                    },
                    {
                        responseType: 'blob',
                    }).then(function(response){
                    let data = response.data;
                    let  headers = response.headers;
                    if (!data) {
                        return
                    }
                    let url = window.URL.createObjectURL(new Blob([data], {
                        type: headers['content-type']
                    }));
                    let link = document.createElement('a')
                    link.style.display = 'none'
                    link.href = url
                    const fileName = headers['content-disposition'];
                    let title = fileName.includes('filename=') ? fileName.split('=')[1] :'下载的表单文件';
                    link.setAttribute('download', title);
                    document.body.appendChild(link)
                    link.click()

                    m.loading = false;
                    m.$Message.success('数据导出成功');
                }, function (error) {
                    m.$Message.error('数据导出错误');
                    m.loading = false;
                })

注意我们发送请求的时候一定要写上responseType,{responseType: 'blob'} 否则下载下来的文件打不开!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章