Translate

[jQuery] Ajax 이용한 파일 다운로드 (Chrome, Firefox, IE11 테스트완료)




이번에 jQuery를 사용하는 프로젝트를 사용하면서 Ajax 다운로드 라이브러리를 사용할까 하다가 그냥 공통파일에 구현을 했다.

크롬, 파이어폭스 익스플로러11 에서 정상적으로 동작하는것을 확인했다.
(2019.10.30)


다운로드 로직
1004lucifer
/**
 * 서버에 요청하여 파일을 다운로드 한다. (Chrome, Firefox, IE11 테스트 완료)
 * @param reqObj 요청정보 -  {
 *     url: 'url',          (required)
 *     method: 'GET|POST',  (optional - default:post)
 *     data: {              (optional)
 *         key1: value,
 *         key2: value
 *     }
 * }
 */
function requestDownloadFile(reqObj) {
    if (!reqObj || !reqObj.url) {
        return;
    }

    var isGetMethod = reqObj.method && reqObj.method.toUpperCase() === 'GET';
    $.ajax({
        url: reqObj.url,
        method: isGetMethod ? 'GET' : 'POST',
        xhrFields: {
            responseType: 'arraybuffer'
        },
        data: $.param(reqObj.data) // a=1&b=2&c=3 방식
        // data: JSON.stringify(reqObj.data) // {a:1, b:2, c:3} JSON 방식

    }).done(function(data, textStatus, jqXhr) {
        if (!data) {
            return;
        }
        try {
            var blob = new Blob([data], { type: jqXhr.getResponseHeader('content-type') });
            var fileName = getFileName(jqXhr.getResponseHeader('content-disposition'));
            fileName = decodeURI(fileName);

            if (window.navigator.msSaveOrOpenBlob) { // IE 10+
                window.navigator.msSaveOrOpenBlob(blob, fileName);
            } else { // not IE
                var link = document.createElement('a');
                var url = window.URL.createObjectURL(blob);
                link.href = url;
                link.target = '_self';
                if (fileName) link.download = fileName;
                document.body.append(link);
                link.click();
                link.remove();
                window.URL.revokeObjectURL(url);
            }
        } catch (e) {
            console.error(e)
        }
    });
}
function getFileName (contentDisposition) {
    var fileName = contentDisposition
        .split(';')
        .filter(function(ele) {
            return ele.indexOf('filename') > -1
        })
        .map(function(ele) {
            return ele
                .replace(/"/g, '')
                .split('=')[1]
        });
    return fileName[0] ? fileName[0] : null
}



해당 함수를 사용하는 코드
1004lucifer
/**
 * 다운로드 함수 사용방법
 */
requestDownloadFile({
    url: 'http://google.co.kr/download.do',
    method: 'POST',
    data: {
        a: 1,
        b: 2,
        c: 3
    }
});




참고
https://codepen.io/chrisdpratt/pen/RKxJNo?editors=1010


댓글

  1. 좋은 글 감사합니다!

    답글삭제
    답글
    1. 도움이 되어 다행이네요.
      즐거운 하루 되세요 ;)

      삭제
  2. 특별한 세션 처리가 없는 경우는 일반 iframe방식이 좋습니다.
    용량이 크면 메모리를 엄청나게 먹는 문제가 생깁니다.

    답글삭제
    답글
    1. 아아.. 그러겠네요.
      세션처리를 하더라도 iframe 방식으로 사용 가능하도록 하는게 대용량 파일 다운로드를 고려한다면 더 좋아보입니다.
      좋은 의견 주셔서 고맙습니다. ^^

      삭제
  3. function requestDownloadFile(){
    var apllyfileName= jQuery('#apllyfileName').val();
    var applyUrl= jQuery('#applyUrl').val();
    var reqObj={
    url: '/pcweb/manage/download',
    method:'POST',
    data: {
    apllyfileName:apllyfileName,
    applyUrl:applyUrl
    }// 데이타 대괄호
    };//reqObj 대괄호
    console.log(JSON.str

    답글삭제
    답글
    1. 이렇게 하고 나머지는 똑같이 작성하였는데
      jquery-2.1.4.min.js:4 Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'arraybuffer').
      at XMLHttpRequest. (http://localhost/static/common/js/jquery-2.1.4.min.js:4:14822)
      (anonymous) @ jquery-2.1.4.min.js:4
      load (async)
      send @ jquery-2.1.4.min.js:4
      ajax @ jquery-2.1.4.min.js:4
      requestDownloadFile @ view:304
      (anonymous) @ VM690:1
      이런 에러문구가 뜹니다... 혹시 이유를 아시나요 ㅠㅠ

      삭제
    2. 소스를 다 올리지 않으셔서 정확하게 알수는 없지만 Ajax 응답의 ResponseText를 읽을 수 없다는 것으로 보여집니다.
      Ajax 호출 부분의 응답을 console.log 로 찍어서 응답 객체에 어떠한 값이 있는지 확인이 필요할것 같아요.

      삭제

댓글 쓰기