解决Ajax/Axios请求下载无效的问题 |
您所在的位置:网站首页 › ajax可以连接数据库吗为什么不能用 › 解决Ajax/Axios请求下载无效的问题 |
解决Ajax/Axios请求下载无效的问题
起因 公司用vue搭了一个前端,现在需要一个文件导出下载的功能,向后台发请求传参下载,too young的我当然是想当然的用了axios发了post请求,结果发现页面死活没有反应。因为后台也是我写的,为了确认不是后台代码的毛病,我把拦截关了用location.href试了试,发现可行,文件下载成功。那么问题就出在axios请求上了。 原因 众所周知,Ajax/Axios请求实际上是通过XMLHttpRequest实现的,具体请自行百度。 request请求只是个“字符型”的请求,即请求的内容是以文本类型存放的。文件的下载是以二进制形式进行,虽然可以读取到返回的response,但只是读取,无法执行。也就是说前端无法调用到浏览器的下载处理机制和程序。 解决方法 通过blob(用来存储二进制大文件)包装ajax(或axios)请求到的data数据,实现下载EXCEL(或其他如图片等)文件。 这里是看到了博客园炫冰G爱的一篇文章,通过blob封装实现下载,原文链接点击这里。 原文: //案例一 axios:设置返回数据格式为blob或者arraybuffer 如: var instance = axios.create({ ... //一些配置 responseType: 'blob', //返回数据的格式,可选值为arraybuffer,blob,document,json,text,stream,默认值为json }) 请求时的处理: getExcel().then(res => { //这里res.data是返回的blob对象 var blob = new Blob([res.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'}); //application/vnd.openxmlformats-officedocument.spreadsheetml.sheet这里表示xlsx类型 var downloadElement = document.createElement('a'); var href = window.URL.createObjectURL(blob); //创建下载的链接 downloadElement.href = href; downloadElement.download = 'xxx.xlsx'; //下载后文件名 document.body.appendChild(downloadElement); downloadElement.click(); //点击下载 document.body.removeChild(downloadElement); //下载完成移除元素 window.URL.revokeObjectURL(href); //释放掉blob对象 }) //案例二 function createDownload(fileName, content){ var blob = new Blob([content]); var link = document.createElement("a"); link.innerHTML = fileName; link.download = fileName; link.href = URL.createObjectURL(blob); document.getElementsByTagName("body")[0].appendChild(link); } createDownload("download.txt","download file"); //案例三 function downloadExport(data) { return axios.post(url, data).then((res)=>{ const content = res const blob = new Blob(["\uFEFF" + content.data],{ type: "application/vnd.ms-excel;charset=utf-8"}) const fileName = '卡密.xls' if ('download' in document.createElement('a')) { // 非IE下载 const elink = document.createElement('a') elink.download = fileName elink.style.display = 'none' elink.href = URL.createObjectURL(blob) document.body.appendChild(elink) elink.click() URL.revokeObjectURL(elink.href) // 释放URL 对象 document.body.removeChild(elink) } else { // IE10+下载 navigator.msSaveBlob(blob, fileName) } }); }下面是我的代码,前端部分: //发送请求 exportExcel(param).then(res => { const blob = new Blob([res]); const fileName = '导出信息.xls'; if ('download' in document.createElement('a')) { // 非IE下载 const elink = document.createElement('a'); elink.download = fileName; elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href);// 释放URL 对象 document.body.removeChild(elink); } else { // IE10+下载 navigator.msSaveBlob(blob, fileName); } });这里在之后的测试中还存在一个问题,用Edge浏览器(没错就是巨硬家的那个)无法下载,在控制台看了一下,是因为response里什么都没有。考虑到Edge浏览器实在是…所以暂时没管它,加了个“使用Edge浏览器无法下载”的提示,之后有必要再改。至于Chrome,FireFox,360,IE等都OK。 后端部分: @RequestMapping(value = "/exportExcelFile",method = {RequestMethod.GET,RequestMethod.POST}) public ResponseEntity export(String deviceCode, String batchNo, @RequestParam(required = false, value = "streetIds") List streetIds, String type) throws IOException { List models = getExportModelList(deviceCode,batchNo,streetIds,type); File file = getExportExcelFile(models,type); System.out.println(file.getName()); byte[] fileBytes = FileUtils.readFileToByteArray(file); file.delete(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", "export.xls"); return new ResponseEntity(fileBytes, headers, HttpStatus.CREATED); }getExportModelList:获取数据 getExportExcelFile:将数据通过OutPutExcel类返回一个file(OutPutExcel是自写类,详情自行百度利用freemaker导出文件) |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |