这几天一直在作远程文件下载的事,如今总算有了解决,特来记录一下踩过的坑和想揍本身的心html
Java
写的,也就是说原始文件存在Java
服务端,返回时有加密措施node
服务器作中间转发Java
接口使用post
方式来请求下载先说总结,下附过程
node
做为文件服务器,能够直接与前端交互时),彻底能够经过拼接GET
请求url
进行模拟点击下载,系统开销还小,响应快。若是像本例中这样的场景会遇到这样一个问题,详见连接 POST
下载。模拟表单
提交POST
请求node
端经过pipe
将responseA
和responseB
串联起来,如responseA.pipe(responseB)
最开始没搞清楚怎么用POST
请求下载且前端该怎样接收和处理,关键字node 前端下载
搜到的绝大多数都是用GET
连接下载,加上刚刚接触node
没有很好理解流的概念,所以一根筋的想如何经过POST
请求转换成GET
请求下载,因而自做主张采用了笨办法
,走上了一条差点没回来的路:前端
post请求A
给node
node
获取参数向Java
端发送post请求B
把文件先下载到node
本地(Java
返回的记为responseA
)并用responseB
返回前端文件地址
和文件名
responseB
后拼接成get请求
模拟a标签
点击去下载node
中的文件node
端对应文件删除。写到这里本身都忍不住想锤本身,给本身挖坑不说,这样来回请求下载,流量double,真的是败家。node
在前端项目根目录下新建
proxy.conf.json
文件,配置接口转发
{ "/api": { "target" : "http://localhost:3000"//server端port } }
保存后,配置package.json
文件里start
命令以下,保存后从新运行就好
"start": "ng serve --proxy-config proxy.conf.json",
前端GET下载的三种方式ios
GET
请求url
赋值给a标签
,模拟点击先获取数据流存进blob
对象,a.href = window.URL.createObjectURL(blob)
git
每次调用createObjectUR
的时候,一个新的URL对象就被建立了.即便你已经为同一个文件建立过一个URL. 若是你再也不须要这个对象,要释放它,须要使用URL.revokeObjectURL()
方法. 当页面被关闭,浏览器会自动释放它,可是为了最佳性能和内存使用,当确保再也不用获得它的时候,就应该释放它.
iframe
,src
设置为如上一步的url
便可前端如何接收文件流并下载github
原生
xhr
请求写法
var xhr = new XMLHttpRequest(); xhr.open("get", url, true); xhr.responseType = "blob"; xhr.onload = function() { if (this.status == 200) { var blob = this.response; var img = document.createElement("img"); img.onload = function(e) { window.URL.revokeObjectURL(img.src); }; img.src = window.URL.createObjectURL(blob); $("#imgcontainer").html(img); } } xhr.send();
axios
请求写法
axios.post("/api/download_reports",msgArr,{ responseType:'blob', onDownloadProgress (a){ //监听下载进度 if(a.lengthComputable){ let percent = (a.loaded*100/a.total).toFixed(2) console.log(percent) $('#percent').html(tempLoaded) } } }) .then(response => { console.log(response) if(response.status == 200){ const blob = new Blob([response.data],{type: 'application/octet-stream'}); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = baseName+'.zip'; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); } }) .catch(error => { console.log(error) })
前端如何获取下载进度,并进一步完成进度条设置ajax
axios.post('/喵',postData, { onUploadProgress (a){ //上传进度同理 console.log(a) }, onDownloadProgress (a){ //控制台输出后,能够发现咱们可以经过a.loaded*100/a.total来得到下载进度 //但需注意的是若是node端的responseB没有设置'Content-Length'即二进制流size的话 //axios.post此时获取到的下载进度事件对象a里lengthComputable为false,进而a.total=0 //进而没法获取百分比进度 console.log(a) } })
前端POST下载的两种方式json
这个没有什么好说的,惟一可能要注意的就是表单里input传参的时候,若是参数比较多,能够用JSON.stringify()转换,只向后端发送一个字符串就好
以上就是本身对node实现文件前端下载的一些理解,若有不妥欢迎交流指正~axios