一、前端发起请求
1、封装的请求:
1 2 3 4 5 6 7 8 9 10
| export function downloadFile(fileUrl) { return request({ responseType: 'blob', url: `/admin/thesis/downloadFile`, method: 'post', data: { fileUrl } }) }
|
注意:这里的 responseType: 'blob' 非常重要!!!
2、调用请求:
1 2 3 4 5 6 7 8 9 10
| downloadThesisFile(thesis){ downloadFile(thesis.filePath).then(resp=>{ const url = window.URL.createObjectURL(new Blob([resp.data])) const link = document.createElement('a') link.href = url link.setAttribute('download', `${thesis.title}.pdf`) document.body.appendChild(link) link.click() }) }
|
这里的 thesis 是调用时的对象参数,里面包含了 filepath、title 等参数。
.pdf 是因为我下载的类型是 pdf 类型
后端处理请求
controller 层:
1 2 3 4 5 6 7 8
| @PostMapping("/downloadFile") public void downloadFile(HttpServletResponse response, @RequestBody Map<String, String> map){ if (CollectionUtil.isEmpty(map) || !map.containsKey("fileUrl")){ return; }
thesisService.downloadFile(map.get("fileUrl"), response); }
|
service 层:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @Override public boolean downloadFile(String fileUrl, HttpServletResponse response) { String path = FileUtil.getPathByUrl(fileUrl);
if (StrUtil.isEmpty(path)){ return false; }
File file = new File(path);
if (!file.exists()){ return false; }
response.reset(); response.setContentType("application/octet-stream"); response.setCharacterEncoding("utf-8"); response.setContentLength((int) file.length()); response.setHeader("Content-Disposition", "attachment;filename=" + file.getName() );
try(BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(file.toPath()));) { byte[] buff = new byte[1024]; OutputStream os = response.getOutputStream(); int i = 0; while ((i = bis.read(buff)) != -1) { os.write(buff, 0, i); os.flush(); } } catch (IOException e) { logger.error("",e); return false; } return true; }
|
这里面夹杂了本系统的业务逻辑,技术逻辑不太清晰。
总结
- 前端封装一个包含
responseType: 'blob' 配置的 api。
- 后端用流的形式把文件写入 HttpServletResponse,并且需要更改其一些配置,比如:
response.setContentType("application/octet-stream"); 等。
- 前端拿到数据后需要用
const url = window.URL.createObjectURL(new Blob([resp.data])) 来处理成 url 等一系列操作来实现下载。