前言
最近项目将token信息放在请求的header中,所以不可以用iframe的src属性下载文件,因为不可以操作请求头。这里记录一下使用axios实现文件下载的方法。
具体实现
- 前端代码
axios({
method: 'post',
url: 'export/download/',
data: {
id: fileId
},
headers: {
'Content-Type': 'application/json',
'token': localStorage.getItem('token')
},
responseType: 'blob'
}).then(res => {
const href = window.URl.createObjectURL(new Blob([res.data])) // 创建下载链接
const a = document.createElement('a')
a.style.display = 'none'
a.href = href
a.setAttribute('download', '123.txt')
document.body.appendChild(a)
a.click() // 下载点击
document.body.removeChild(a) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放blob对象
})
- 后端代码
@RequestMapping(value = "/download", method = RequestMethod.POST)
public void download(@RequestBody Map<String, Object> param, HttpServletRequest req, HttpServletResponse resp) {
String fileId = (String) param.get("id");
File file = new File("....." + fileId);
.........
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
OutputStream fos = null;
try {
bis = new BufferedImputStream(new FileInputStream(file));
fos = resp.getOutputStream();
bos = new BufferedOutputStream(fos);
.......
setHeader等等操作
......
resp.setContentType("application/octet-stream");
int byteRead = 0;
byte[] buffer = new byte[8192];
while ((byteRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, byteRead);
}
} catch(Exception e) {
} finally {
try {
bos.flush();
bis.close();
fos.close();
bos.close();
file.delete();
} catch {
}
}
}
注意事项
1.前端代码中,responseType: 'blob'
很重要。
2.前端代码中,向后台传参用的json,所以headers
的Content-Type
中用application/json
,相应后台用@RequestBody Map<String, Object> param
接收参数。
3.后台代码中resp.setContentType("application/octet-stream");
很重要。
4.后台下载的文件格式可以为txt,pdf,csv等,相应前台文件名也要以这些结尾。