咱们一般下载文件的方式无非后端给一个生成文件连接, 前端经过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