记录一次axios接收文件流的尝试。最近在写一个代码生成工具,涉及到服务器生成代码进行压缩,传给页面进行下载。
# 后端接口编写
后端使用 Spring Boot 进行接口响应
@PostMapping(value = "/project/code/download") | |
@ResponseBody | |
public void downloadCode(@RequestBody TProjectInfo pf, HttpServletResponse response) { | |
// 0. 保存此次生成的项目配置 | |
// 1. 生成源码文件 | |
// 2. 压缩文件 | |
// 3. 设置回复的一些参数 | |
// 4. 将压缩文件写入网络流 | |
log.info("request param: {}", pf); | |
projectService.saveOrUpdate(pf); | |
String filename = "./src/main/resources/templates/test/源码233.zip"; | |
File file = new File(filename); | |
// 如果文件存在,则进行下载 | |
if (file.exists()) { | |
BufferedInputStream bis = null; | |
OutputStream os = null; | |
try { | |
// 配置文件下载 | |
// 下载文件能正常显示中文 | |
response.setHeader("Content-Disposition", "attachment;filename=" | |
+ URLEncoder.encode(file.getName(), "UTF-8")); | |
response.setHeader("content-type", "application/octet-stream"); | |
response.setContentType("application/octet-stream"); | |
// 实现文件下载 | |
byte[] buffer = new byte[1024]; | |
bis = new BufferedInputStream(Files.newInputStream(file.toPath())); | |
os = response.getOutputStream(); | |
int i = bis.read(buffer); | |
while (i != -1) { | |
os.write(buffer, 0, i); | |
i = bis.read(buffer); | |
} | |
log.info("Download successfully!"); | |
} catch (Exception e) { | |
log.error("Download failed: {}", e.getMessage()); | |
} finally { | |
if (os != null) { | |
try { | |
os.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
if (bis != null) { | |
try { | |
bis.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
} |
接口返回 data:
# axios 接收并下载
assit.post('/project/code/download', obj, { | |
responseType: 'blob', // 此处必须设置 | |
onDownloadProgress: function (pe) { | |
// Do whatever you want with the native progress event | |
console.log(Math.round(pe.loaded / pe.total * 100) + '%') | |
}}).then(r => { | |
const blob = new Blob([r.data]); // { type: "application/vnd.ms-excel" } | |
let url = URL.createObjectURL(blob); // 创建一个临时的 url 指向 blob 对象 | |
// 创建 url 之后可以模拟对此文件对象的一系列操作,例如:预览、下载 | |
const a = document.createElement("a"); | |
a.download = obj.projectName + ".zip"; | |
a.style.display = "none" | |
a.href = url; | |
document.body.appendChild(a) | |
a.click(); | |
// 释放这个临时的对象 url | |
URL.revokeObjectURL(url); | |
document.body.removeChild(a) | |
}).catch(e => { | |
console.log(e) | |
}) |
# 错误记录
- axios 请求时未配置
responseType: 'blob'
,虽然能正常下载,但是会出现数据格式错误: