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'} 否则下载下来的文件打不开!!!

 

关注

如果有问题,请在下方评论

想获得更多的学习知识请关注微信公众号:西北码农或扫下方二维码


 

全部评论

相关推荐

美团开奖了,谁说测开比后端薪资低?谁说前端比后端薪资低?好了你又要说后端可以争取sp、ssp,但是能拿到美团白菜offer的就已经算是人中龙凤了,拿到sp、ssp更是凤毛麟角!依旧劝退后端!你后端学历内卷炼狱!实习经历卷的爆!甚至无法入行!入行了也只是和测开、前端的一般!1.学历,最痛的一击!后端工程师的第一步,走得不是技术,而是学历!想要进入大厂?好好看清楚自己的身份证:没有名校背景,别想着进美团、字节、腾讯! 面试官看你的第一眼就会想:“呵,去,给你点面试机会,看看你的技术!”什么?你说自己有技术?不好意思,来点GitHub链接,Project经历,能让面试官笑着赶你走。你没个985、211,双一流,根本就无法站稳在这场技术竞赛的起点。你想进大厂,没学历,没技术!永远只有一个词—— “被无情拒绝”。2. 薪资:你不过是和前端、测开的一匹马“后端工程师薪资高?能进SSP就是牛逼!”SSP? 听起来像是你梦想的银河,但实际上能拿到这个级别的人 凤毛麟角,除非你在面试官面前像神话人物一样打了个响指,否则你连SSP的尾巴都摸不着。至于你说的“前端薪资不高”?别逗了,前端都在笑你呢, 他们搞个页面,工资比你写个亿级请求接口还多。你说你辛辛苦苦优化API、调度缓存,别人搞个UI设计就能多拿几千块。前端已经不止是个展示层了,他们赚得比你还轻松,而你不过是服务器上疯狂跑“CRUD操作”的那只笨重的工蚁。3. 后端的真正意义:修 Bug,解决问题,下一份工作还是修 Bug有多少人觉得后端是系统架构、数据库优化的高端战场?醒醒吧! 后端的真正使命:维护旧项目,修复别人留下的烂摊子。你觉得自己能构建一个完美的系统?不!你只会一边修复技术债务,一边打着 “重构” 的旗号,换来的是 “重构再重构” 的无尽循环。而且,别告诉我你能专心写代码。你又要写代码,又要看服务器日志,没事还得帮别人 修崩的数据库,给前端数据源做“格式化”。你就是那块永远处于消耗型工作的 “万金油”。4. 晋升?哈哈哈,你是在做梦!你以为后端开发是一条顺风顺水的快速晋升路线?错! 你永远只能在一个“程序员”的岗位上打转,或者你为自己设立目标:“我要成为架构师”,那真的是在妄想。架构师?高级开发?靠近那条道路,你的心脏会先被晋升难度给捏住,你前方只有一座座高不可攀的技术山。别看那些SSP,架构师,架构啥呀?公司里的架构都是前端架构师,你就坐在后端的角落里,照顾着你那些满是错误的API和服务器。5. 加班?还是加班!你以为后端开发能像文艺片那样“偶尔加个班”?哈哈,傻了吧! 后端开发的生活是无休止的加班和修bug,你不仅要写接口,还得守夜调度、监控系统性能。就连你写的那个“完美的数据库查询”,也可能在 第二天 被前端因为“页面卡顿”给打回原形。“没有加班,你还能吃什么饭?”你说你是程序员,结果你的生活全是 熬夜加班、调试、重启。前端跑个页面,喝个咖啡就能过关,而你呢,熬夜跟数据库调试,最后还是那个穷忙的死循环。6. 技术天花板:架构?技术深度?笑死了!后端开发的天花板?那不过是个永远也摸不着的架构师“梦想”,你能掌握几款框架、几种数据库、两三套微服务架构,最后也不过是个 管理端的“搬运工”。你没办法“打破天花板”,更没有机会跳出“自己写个爬虫”或者“API接口”的死循环。技术深度?你也不过是 “技术债务”的修复者,一天到晚都在修补“老旧系统”的缺陷,偶尔听前端同学聊聊他们React、Vue的最新版本,你根本无法理解他们说的是什么。
开心小狗🐶:感觉后端有点像考研的0812,报名的时候都想冲0812,看不上0854。但是真入学了,不都是众生平等
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务