咱們一般下載文件的方式無非後端給一個生成文件連接, 前端經過a標籤或者iframe的方式去下載,這種方式的弊端是沒法監測到文件是否下載完成,沒法給用戶友好的提示,以免用戶短期內重複點擊下載.前端
若是咱們能用Ajax從後端拿到PDF的相關數據,再在前端下載成PDF就能夠解決這個問題,那麼新的問題是:ajax
1. 前端如何下載PDF?後端
2. 後端給什麼格式的數據?app
針對第一個問題很簡單:將經過URL.createObjectURL()函數將blob對象生成url,並添加到a標籤上便可解決.函數
問題轉化成後端給什麼格式數據咱們經過ajax請求獲取以後能夠轉化成blob? base64是一個可行的方案.url
具體解決方案以下:spa
1. 將base64轉化成blob方法code
1 function convertBase64ToBlob(base64, fileType, slice) { 2 return new Blob(atob(base64) 3 .match(new RegExp(`([\\s\\S]{${slice}})|([\\s\\S]{1,${slice}})`, 'g')) 4 .map(function(item){ 5 return new Uint8Array(item.split('').map(function(s, i) { 6 return item.charCodeAt(i) 7 })) 8 }), {type: fileType}) 9 }
2. 前端下載PDF對象
1 const blob = convertBase64ToBlob(data, 'application/pdf', 1024) 2 if (navigator.msSaveBlob) { 3 return navigator.msSaveBlob(blob, '1.pdf'); 4 } 5 const urlFromBlob = window.URL.createObjectURL(blob); 6 const a = document.createElement('a'); 7 a.style.display = 'none'; 8 a.href = urlFromBlob; 9 a.download = '1.pdf'; 10 document.body.appendChild(a); 11 a.click(); 12 window.URL.revokeObjectURL(urlFromBlob); 13 document.body.removeChild(a)
over !blog