思路:前端向后端请求下载文件流,后端返回文件流再进行下载
download(fileName){
let param = {
fileName:fileName
}
apiDownLoad('/api/downloadFile',param).then(res=>{
var blob = new Blob([res],{type: "application/octet-stream"});
if (window.navigator.msSaveOrOpenBlob) {//msSaveOrOpenBlob方法返回bool值
navigator.msSaveBlob(blob, fileName);//本地保存
} else {
var link = document.createElement('a');//a标签下载
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
window.URL.revokeObjectURL(link.href);
}
})
}
export function apiDownLoad(url,data){
return new Promise((resolve) =>{
axios({
method:'get',
url:url,
params:data,
responseType:'blob'
}).then(res =>{
resolve(res.data);
}).catch(err =>{
resolve('error');
})
})
}
apiDownLoad是axios封装了一个get请求,重点配置responseType:’blob’,解决文件内容乱码。
后台使用Springboot,JAVA代码如下:
@GetMapping("/downloadFile")
public ResponseEntity<FileSystemResource> downloadFile(@RequestParam(name = "fileName") String fileName) throws Exception {
//获得完整的路径
String path="D://share/"+fileName;
//输出路径
System.out.println("path:"+path);
File file = new File(path);
System.out.println("fileName:"+file.getName());
//处理文件名中文编码
String myFileName= URLEncoder.encode(file.getName(), "utf-8");
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + myFileName);
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Last-Modified", new Date().toString());
headers.add("ETag", String.valueOf(System.currentTimeMillis()));
return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
}