前端如何实现下载功能(后端返回文件流,前端如何处理)

工作中经常会遇到下载功能,后端有时返回一个文件服务器地址,有时候直接返回文件流。自己对这一块也比较模糊,跟着度娘每次艰难的实现功能。痛定思痛,对下载功能进行一下小小的研究,做一个记录,也希望帮到有需要的小伙伴。

如果是实现同源文件的下载可以直接通过a标签的download来实现,这个就比较简单

a标签

<a href="http://www.XXXX.com" download="XXXX.html">下载</a>

download是h5新增的属性,在这里进行一下说明,后面内容会用到。这个属性用来指定下载文件的名字。想要深入了解可以查看文档。

const a = document.createElement('a')
a.href = 'http://XXX.baidu.com'
a.download = 'XXX.html'
a.click()

如果不想在页面上显示a标签可以通过动态生成的方式来实现。

window.open()

window.open('http://www.XXX.com', '_blank')
 // _black用来指定在新页面打开,不指定在当前页面打开

这种方式不能下载.html、.htm、.xml、.xhtml等文件。
如果是同源文件下载用以上方法简单明了,其实说白了,前端的文件下载都是基于浏览器机制。
对于跨域文件的下载,做以下几种说明。
我们在做项目中,经常会把接口放在一个js文件中进行统一管理,我的项目是vue、axios,代码仅作参考。

export function api(data) {
    return request({
        responseType: 'blob', // *responseType设置为 blob*
        url: '/xxxx/xxxxxxxx',// 接口地址
        method: 'post',
        data
    });
}

与正常接口写法一直,多写一行 responseType: ‘blob’。接下来就是正常的调接口环节,使用async/await或者promise都可,看个人习惯。

 api(data).then(res => {
                if (res) {
                   let index = res.data[0].uploadFilePath.indexOf('.')
       		    	let type = res.data[0].uploadFilePath.substring(index + 1)
     			    let filename = res.data[0].uploadFileName
                    var a= document.createElement('a');
                    a.download = filename + '.' + type;
                    // 指定文件名,根据实际情况指定
                    var blob = new Blob([res], { type: 'application/x-msdownload' });
                    a.href = URL.createObjectURL(blob);
                    document.body.appendChild(a);
                    a.click(); // 点击创建的a标签
                    document.body.removeChild(a);// 移除a标签,用完释放是一个好习惯
                } else {
                    this.$message.error('下载异常');
                }
            }).catch(err => {
                console.log(err);
            });

这里涉及到blob 和URL.createObjectURL两个点,做一个简单说明

Blob对象

Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。

创建中使用了type属性,其实Blob有两个属性(size和type),size属性是表述文件的大小,type 是 MIME 类型的字符串。
想要了解Blob的小伙伴可以看https://zhuanlan.zhihu.com/p/161000123,这个博主讲解的很好,这里作为文件下载的文章不做太多赘述。

URL.createObjectURL

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL
的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。

这个方法是将Blob对象转化成一个url,通过这个url实现下载。

ajax

通过ajax也是几乎一样的写法

   const x = new XMLHttpRequest()
        x.open('GET', url, true)
        x.responseType = 'blob' // 指定responseType 
        x.onload = function () {
          const url = window.URL.createObjectURL(x.response)
          const a = document.createElement('a')
          a.href = url
          a.download = filename + '.' + type
          a.click()
        }
        x.send()

总结来说,就是将请求回来的文件流转化成Blob对象,然后将Blob对象转化成一个url,通过a标签的形式进行点击下载。
通过看别人的文章还可以使用FileSaver.js插件,欢迎补充

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值