- 下載過程當中,獲取進度,fetch API並無提供相似xhr和ajax的 progress因此用 getReader()來循環讀取大小
let size = 0; fetch( URL() + `/sys/file/download/${uuid}`,{ method: 'GET', headers:{ token, } }) .then(response => { if(response.ok){ return response; }else{ console.log("請求失敗") } }) // 取出body .then(response => response.body) .then(body => { const reader = body.getReader(); return new ReadableStream({ start(controller) { return pump(); function pump() { return reader.read().then(res => { //res ({ done, value }) // 讀不到更多數據就關閉流 console.log(res,"res"); const {done,value } = res; if (done) { console.log("end") controller.close(); // return; } size += value.length || 0; console.log(size,"size") // 將下一個數據塊置入流中 controller.enqueue(value); return pump(); }); } } }) }) .then(stream => new Response(stream)) .then(response => that.savingFile(response,fileName)) .catch(err => console.error(err));
- 上一步中接收到文件流後,經過Blob和a標籤進行下載
savingFile = (response,fileName) => { const that = this; response.blob().then( blob => { if(typeof FileReader === 'undefined'){ notification.open({ message:'您的瀏覽器不支持 FileReader,請升級瀏覽器', icon: <Icon type="smile" style={{ color: '#108ee9' }} /> }) } const reader = new FileReader(); reader.addEventListener("loadend", function() { let resu = ''; try{ resu = JSON.parse( reader.result); // resu = eval('('+ reader.result + ')') if(resu.code == 500){ notification.open({ message:resu.msg, icon: <Icon type="smile" style={{ color: '#108ee9' }} /> }) }else if(resu.code == 401){ notification.error({ message:resu.msg }) } }catch(e){ //捕獲錯誤 說明是文本字符串 resu = reader.result; downloadBlob(blob,fileName); } }); reader.readAsText(blob); //下載 function downloadBlob(blob,fileName){ let blobUrl = window.URL.createObjectURL(blob); let a = document.createElement('a'); a.href = blobUrl; a.target = '_blank'; a.style.display = 'none' document.body.appendChild(a) a.download = fileName; a.click(); window.URL.revokeObjectURL(blobUrl); document.body.removeChild(a) that.setState({ downloading:false }) } }) }
總結一下: 這種前端下載的方式,感受體驗還不是很好。主要考慮是文件流的下載方式,是先下載徹底部數據才彈出保存窗口,而大部分軟件下載的網站是用a標籤直接下載的。這樣是先彈出窗口,再利用瀏覽器的下載工具進行下載,雖然少了一些定製顯示,但用戶體驗上應該會好一點。 再找個下載文件的網站參考參考。前端