本次下载是后台文件流传输,前端下载,前端将拿到的下载id和名称downloadName传递给下载方法;如果是多个下载,可以采用数组for循环
情景描述:
1.如果符合导出条件, 后端直接返回数据流,如下图所示的一堆看不懂的东西:
2.不满足导出条件, 则后端返回JSON, 并附上失败原因, 前端需要将失败原因展示出来
解决问题:
- 兼容ie浏览器下载报传递给系统调用的数据区域太小.
- 解决blob下载文件,文件下载失败将blob的错误信息转换成json格式
//下载downloadFile() {let obj = {loginUser: this.$store.state.loginUser,id: this.visibleId,};axios.post(this.$store.state.windowCONTENT + "myDownload/downloadFile",obj,{responseType: "blob",}).then((res) => {// console.log(res.data.type);// alert(res.data.type);//此时有点两种情况,1.后端返回的是个对象而不是文件,但是被我们获取时候转成了blob,导致我们没法做判断。//例如{data:"参数异常,无下载权限",message:"INPUT_PARAMETER_CHECK_ERROR",success:7}//故需要将获取到的blob类型做判断,如果是application/json ---谷歌下的对象转blob的类型,或者application/json;charset=utf-8---ie下的对象转blob的类型//然后在再讲此blob转成原对象做判断if (res.data.type.includes('application/json')) {//以下部分代码是将原来的{}json对象转成的blob文件流,重新再读写成json对象做判断let reader = new FileReader()reader.onload = (event) => {let content = JSON.parse(reader.result)console.log(content);let message = content.message // 错误信息let status = content.success //状态码// 错误处理--根据后端实际返回的对象做判断if (status == 7) {alert(message);} else if (status == 9) {}}reader.readAsText(res.data)return true} else {if ("msSaveOrOpenBlob" in navigator) {//兼容ie浏览器下载报传递给系统调用的数据区域太小.var data = res.data;var blob = new Blob([data], { type: "application/vnd.ms-excel" });window.navigator.msSaveOrOpenBlob(blob, this.downloadName);return;} else {// console.log(res.data);const blob = res.data;const reader = new FileReader();reader.readAsDataURL(blob);reader.onload = (e) => {const a = document.createElement("a");a.download = this.downloadName; //点击下载时候传递过来的文件名称包括本身的格式 例如 帮助文档.doca.href = e.target.result;// console.log(e.target.result);document.body.appendChild(a);a.click();document.body.removeChild(a);};}}}).catch((err) => {console.log(err.message);});},
- 可参考链接
2.地址栏方式下载:一般接口返回下载地址
// 下载download(id) {queryPdf(id).then(res => {if (res.code === 200) {const a = document.createElement('a')a.style.display = 'none'a.setAttribute('href', res.data)a.click()}})},