반응형
결론부터 말하자면 xhr.responseType = "blob" 로 설정해야 한다!
기존에 사용하던 제이쿼리 버전이 1.11.1이였는데 이 버전은 blob이 적용안되더라..
버전 문제인줄 모르고 한참을 씨름 했는데 3.6.0으로 올리니까 해결됐다. (어떤 버전부터 되는 건지는 모르겠음)
아래 예시 참조!!
let options = {
url: "[[@{/}]]download"
, beforeSubmit : loadingAjaxImage
, contentType: "application/x-www-form-urlencoded;charset=UTF-8"
, xhr: function () {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
//response 데이터를 바이너리로 처리한다. 세팅하지 않으면 default가 text
xhr.responseType = "blob";
};
return xhr;
}
, type: "post"
, success: function (data, message, xhr) {
hideAjaxImage();
if (xhr.readyState == 4 && xhr.status == 200) {
// 성공했을때만 파일 다운로드 처리하고
let disposition = xhr.getResponseHeader('Content-Disposition');
let filename;
if (disposition && disposition.indexOf('attachment') !== -1) {
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
let matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
let blob = new Blob([data]);
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
}else{
//실패했을때는 alert 메시지 출력
alertPopup("다운로드에 실패하였습니다.");
}
}
};
$("#testForm").ajaxSubmit( options );
}
ajax로 바꾼 이유
대량의 데이터라 생성하고 다운로드 처리하는 시간이 오래 걸리기 때문에 로딩이미지를 호출하기 위해서다
beforeSubmit : loadingAjaxImage -> 로딩 이미지 호출하는 부분
Controller 예시
@RequestMapping("/download")
public ResponseEntity<?> download(@ModelAttribute TestVo testVo, HttpSession session){
FileVo vo = this.testService.download(testVo);
if(vo.getFileData() != null) {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + vo.getFileName() + "\"")
.body(vo.getFileData());
}else{
return ResponseEntity.noContent().build();
}
}
이렇게 파일이 다운로드 된다!
728x90
반응형
'개발 > JavaScript' 카테고리의 다른 글
[JavaScript] var, let, const 비교 - var is used instead of let or const (1) | 2022.01.24 |
---|
댓글