以下是工作中前端常见的文件下载的几种方法。欢迎大家补充指正。
一、location.href
对于一些浏览器无法识别的文件格式,可以直接再浏览器地址栏输入url即可触发浏览器的下载功能。对于单文件下载没有什么问题,但是如果下载多文件,点击过快就会重置掉前面的请求。
适用场景:
- get请求
- 单文件下载
window.location.href = url;
二、window.open
和location.href类似
window.open(url);
三、a标签
直接下载仅适用于浏览器无法识别的文件。如果是浏览器支持的文件格式,如html、jpg、png、pdf等,则不会触发文件下载,而是直接被浏览器解析并展示,这种情况下,可以使用a标签下载文件,download属性可以设置文件名。适用于单文件下载,如果下载多文件,点击过快就会重置掉前面的请求。
适用场景:
- get请求
- 单文件下载
- 需要自定义文件名
//写法1 const download = (filename, url) => { let a = document.createelement('a'); a.style = 'display: none'; // 创建一个隐藏的a标签 a.download = filename; a.href = url; document.body.appendchild(a); a.click(); // 触发a标签的click事件 document.body.removechild(a); } // 写法2 <a href="/images/download.jpg" rel="external nofollow" download="myfilename">
注意:有时候对于浏览器可识别的文件格式,我们还是需要直接下载的情况,可以声明一下文件的header的 content-disposition信息,告诉浏览器,该链接为下载附件链接,并且可以声明文件名。
content-disposition: attachment; filename="filename.xls"
四、文件流
如果需要使用post请求,且后端返回是一个文件流形式,那么前端需要自己将文件流转成链接,然后下载。 二进制流大概长这样:
适用场景:
- post请求
- get请求
- 多文件
1.请求的方式
注意:不可以使用jquery,因为jquery不支持blob类型。
原生js写法
const req = new xmlhttprequest(); req.open('post', '/download/excel', true); req.responsetype = 'blob'; //如果不指定,下载后文件会打不开 req.setrequestheader('content-type', 'application/json'); req.onload = function() { var content = req.getresponseheader("content-disposition") ; // 文件名最好用后端返的content-disposition // 需要后端设置 access-control-expose-headers: content-disposition 使得浏览器将该字段暴露给前端 var name = content && content.split(';')[1].split('filename=')[1]; var filename = decodeuricomponent(name) downloadfile(req.response,filename) }; req.send( json.stringify(params));
axios写法
axios({ method: 'post', headers: { 'content-type': 'application/json; charset=utf-8' }, url: '/robot/strategymanagement/analysisexcel', responsetype: 'blob', headers: { //如果需要权限下载的话,加在这里 authorization: '123456' } data: json.stringify(params), }).then(function(res){ var content = res.headers['content-disposition']; var name = content && content.split(';')[1].split('filename=')[1]; var filename = decodeuricomponent(name) downloadfile(res.data,filename) })
2.文件下载的方式
通过url.createobjecturl()下载
url.createobjecturl() 静态方法会创建一个domstring,其中包含一个表示参数中给出的对象的url。这个 url 的生命周期和创建它的窗口中的document绑定。
downloadfile:function(data,filename){ // data为blob格式 var blob = new blob([data]); var downloadelement = document.createelement('a'); var href = window.url.createobjecturl(blob); downloadelement.href = href; downloadelement.download = filename; document.body.appendchild(downloadelement); downloadelement.click(); document.body.removechild(downloadelement); window.url.revokeobjecturl(href); }
通过# filereader.readasdataurl()下载
readasdataurl() 方法会读取指定的 blob 或 file 对象。读取操作为异步操作,当读取完成时,可以从onload回调函数中通过实例对象的result属性获取data:url格式的字符串(base64编码),此字符串即为读取文件的内容,可以放入a标签的href属性中。
downloadfile:function(data,filename){ const reader = new filereader() // 传入被读取的blob对象 reader.readasdataurl(data) // 读取完成的回调事件 reader.onload = (e) => { let a = document.createelement('a') a.download = filename a.style.display = 'none' // 生成的base64编码 let url = reader.result a.href = url document.body.appendchild(a) a.click() document.body.removechild(a) } }
两者的区别
- 返回值 filereader.readasdataurl(blob)可以得到一段base64的字符串。
url.createobjecturl(blob)得到的是当前文件的一个内存url
。 - 内存 filereader.readasdataurl(blob)依照js垃圾回收机制自动从内存中清理。 url.createobjecturl(blob)存在于当前document内,清除方式通过revokeobjecturl()手动清除。
- 执行方式 filereader.readasdataurl(blob)通过回调的方式f返回,异步执行。
url.createobjecturl(blob) 直接返回,同步执行。 - 多个文件 filereader.readasdataurl(blob)同时处理多个文件时,需要一个文件对应一个filereader对象url.createobjecturl(blob) 依次返回,没有影响。
- 优势对比 url.createobjecturl(blob)得到本地内存容器的
url
地址,方便预览,需要注意手动释放内存的问题,性能优秀。
filereader.readasdataurl(blob)可直接转为base64
格式,直接用于业务。
总结
到此这篇关于前端实现文件下载常见的几种方法的文章就介绍到这了,更多相关前端文件下载方法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论