我們通常下載文件的方式無非後端給一個生成文件鏈接, 前端通過a標簽或者iframe的方式去下載,這種方式的弊端是無法監測到文件是否下載完成,無法給用戶友好的提示,以避免用戶短時間內重覆點擊下載. 如果我們能用Ajax從後端拿到PDF的相關數據,再在前端下載成PDF就可以解決這個問題,那麼新的問題是: ...
我們通常下載文件的方式無非後端給一個生成文件鏈接, 前端通過a標簽或者iframe的方式去下載,這種方式的弊端是無法監測到文件是否下載完成,無法給用戶友好的提示,以避免用戶短時間內重覆點擊下載.
如果我們能用Ajax從後端拿到PDF的相關數據,再在前端下載成PDF就可以解決這個問題,那麼新的問題是:
1. 前端如何下載PDF?
2. 後端給什麼格式的數據?
針對第一個問題很簡單:將通過URL.createObjectURL()函數將blob對象生成url,並添加到a標簽上即可解決.
問題轉化成後端給什麼格式數據我們通過ajax請求獲取之後可以轉化成blob? base64是一個可行的方案.
具體解決方案如下:
1. 將base64轉化成blob方法
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 !