這幾天一直在作遠程文件下載的事,如今總算有了解決,特來記錄一下踩過的坑和想揍本身的心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