上传和下载是前端er们经常遇到的场景,上传还可以用element、iview等各种封装好的组件,下载则不然,常常需要写很多的代码,而且经常跟后端对接失败,有时候真是心里mmp。好了,接下来分享一下自己经常使用的3种下载方式,有需要的同学请自取,自己也相当于做个整理回顾。
-
window.open的方式
此种方式最low,然而却是最省事的,因此经常被某些爱省事的后端拿来就用。
使用方式:window.open(url),url既可以是绝对路径,也可以是相对路径。需要注意的是,拼接的链接一定要是合法的url,我在很长的一段时间里不知道如何正确地拼接数组参数的url,实在是惭愧,直到后来了解到有encodeURIComponent这个神器…
缺点:新打开页面,影响交互体验;直接下载,不能自定义文件名,文件存放位置
//导出列表 exportList(obj) { let link = window.globalConfig.defaultProxyPath + url + "/key/person/export?idNums=" + encodeURIComponent(JSON.stringify(obj)); window.open(link); }, -
虚拟表单的方式
表单的下载历史可谓源远流长,下文中的jq调用方式,原理没变,同样是生成虚拟表单,然后模拟提交事件,然后销毁虚拟表单。但是都9102年了还用这种方式来下载,不可谓不low。
缺点:过时
//生成虚拟表单,然后手动触发提交事件 downLoadFile(options) { //let $ = $.noConflict(); let config = $.extend( true, { method: "post" }, options ); let tmpIframe = $('<iframe id="down-file-iframe" />'); let tmpForm = $( '<form target="down-file-iframe" method=" ' + config.method + '" />' ); tmpForm.attr("action", config.url); for (let key in config.data) { tmpForm.append( '<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />' ); } tmpIframe.append(tmpForm); $(document.body).append(tmpIframe); tmpForm[0].submit(); tmpIframe.remove(); } //调用 this.downLoadFile({ url: predix + `/rs/namelist/blackreport`, data: param }); -
文件流式下载
H5其实提供了很多很好用的api,流文件下载就是其中一种。在向后端发送请求时,我们只需要将header中的content-type设置成我们想要的格式,便能得到想要的流文件,从而触发浏览器的下载功能。
优点:简洁,绿色,可自定义文件名和文件存放位置
注意:此方法并不是万无一失,关于header的设置需要前后端对接清楚,在某些情况下,比如跨域,headers的某些属性将会受限,需要后端要较高的素养
//发出请求 download(url, param) { let resType; if (window.navigator.msSaveOrOpenBlob) { // for IE resType = "arraybuffer"; } else { resType = "blob"; } return axios({ url: url, method: "post", responseType: resType, headers: { Accept: "application/octet-stream" }, data: param }); }, //得到文件 real_download(obj) { this.download("/rs/experiment/graph/export", obj).then(res => { let blobObject = new Blob([res.data]); // 获取文件名 let disposition = res.headers["content-disposition"] ? res.headers["content-disposition"] : ""; let filename = decodeURI(disposition.split("filename=")[1]); // let filename = row.fileName; if (window.navigator.msSaveOrOpenBlob) { // for IE window.navigator.msSaveOrOpenBlob(blobObject, filename); } else { const file = window.URL.createObjectURL(blobObject); const link = document.createElement("a"); document.body.appendChild(link); link.setAttribute("download", filename); link.setAttribute("href", file); link.click(); //URL对象释放内存 window.URL.revokeObjectURL(file); link.remove(); } }); },总结:简单说了下3种方式,主要还是自己做个记录,不爱查资料,全凭自己理解,错漏之处还望大家海涵。