배경
사용자가 페이지에서 내보내기를 클릭한 후 페이지에 대한 사용자 입력을 기반으로 백엔드에 양식을 제출합니다. 백엔드가 처리된 후 인적 자원 시스템의 인터페이스를 호출하여 데이터를 쿼리합니다. 인적 자원 시스템은 쿼리 결과를 서버에 저장하고 파일을 다운로드합니다.
질문
오류는 없지만 다운로드할 수 없습니다.
이유
Ajax를 사용하여 파일을 다운로드할 때 브라우저를 실행하여 파일 저장 대화 상자를 열 수 없으며 다운로드한 파일을 하드 디스크에 저장할 수 없습니다! Ajax에서 요청한 데이터는 자바스크립트 메모리 공간에만 저장이 가능하기 때문에 자바스크립트를 통해서는 접근이 가능하지만, 자바스크립트가 하드디스크와 직접 상호작용할 수 없기 때문에 하드디스크에 저장할 수 없으며, 그렇지 않으면 보안상의 문제가 발생한다.
암호
프런트엔드 코드
downloadFile (row) {
this.$axios({
url: '/help/downloadFile',
method: 'post',
responseType: 'blob',// 一定要设置这个,否则会出现乱码
data: {
fileUrl: row.fileUrl,
fileName: row.fileName
}
})
.then(res => {
if (!res.data) {
return
}
// application/msword 表示要处理为word格式
// application/vnd.ms-excel 表示要处理excel格式
let url = window.URL.createObjectURL(new Blob([res.data]), {
type: 'application/msword;charset=UTF-8' })
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', row.fileName)
document.body.appendChild(link)
link.click()
// 释放URL对象所占资源
window.URL.revokeObjectURL(url)
// 用完即删
document.body.removeChild(link)
})
.catch(res => {
})
},
백엔드 코드
@PostMapping("/downloadFile")
public void downloadFile(@Valid @RequestBody FileDownload fileDownload, HttpServletResponse response) throws IOException {
if (!fileDownload.getFileUrl().startsWith(FileConstants.RESOURCE_PREFIX)){
throw new BaseException("File does not exist");
}
String fileUrl = fileDownload.getFileUrl().replace(FileConstants.RESOURCE_PREFIX,FileConstants.PROFILE);
File file = new File(fileUrl);
if (!file.exists()){
throw new BaseException("File does not exist");
}
ServletOutputStream out = null;
try {
byte[] fileArray = FileUtils.readFileToByteArray(file);
out = response.getOutputStream();
out.write(fileArray);
}catch (Exception e){
if (out != null){
out.close();
}
}
}