我们都知道下载文件有一种很简单的方法:window.open(url),但是window.open(url)只是一个纯粹的访问下载文件的链接,并不能满足所有下载文件的需求。
1.前端下载文件有时候会根据权限去下载(需要获取登录的token)
2.有时后端提供的是post请求的接口
3.自定义文件名
这时就需要用到blob啦:
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据
方法:
在请求头部添加responseType:"blob"
responseType属性是一个枚举类型的属性,返回响应数据的类型。它允许我们手动的设置返回数据的类型。
当下载文件时,axios配置responseType: ‘blob’,此时后台返回的数据会被强制转为blob类型;如果后台返回代表失败的data,前端也无法得知,依然会下载得到名为undefined的文件。
解决:将blob转回json格式,通过code判断是否下载成功
axios配置:(angular调用)
axios({ method: 'post', url: '/beisenassess/getExamDetailByCandidateId', responseType: 'blob', }) .then(res => { // 假设 data 是返回来的二进制数据 const data = res.data const jsonData = JSON.parse(res) if(jsonData.code !='200'){ alert('下载失败') return } const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})) //以本地方式保存文件 if(window.navigator && window.navigator.msSaveOrOpenBlob){ window.navigator.msSaveOrOpenBlob(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}), '下载文件.xlsx'); }else{ const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', '下载文件.xlsx') document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(url) } });
ajax的调用:
$('#export').on('click',function(){ var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.setRequestHeader('Content-type','application/json'); xhr.responseType = 'blob'; xhr.onload = () => { if (xhr.status === 200) { //var blob = xhr.response; var blob=new Blob([this.response],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); filename='下载文件.xlsx'; //ie if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, filename); } else { const link = document.createElement('a'); const body = document.querySelector('body'); link.href = window.URL.createObjectURL(blob); link.download = filename; // fix Firefox link.style.display = 'none'; body.appendChild(link); link.click(); body.removeChild(link); window.URL.revokeObjectURL(link.href); } } } xhr.send(); });