728x90
반응형

Ajax 로 구현한 비동기 멀티 파일 업로드 


회사 솔루션에서 .eml파일과 .zip 파일을 ActiveX를 이용하여 서버에 업로드하는 기능이 있었는데 

알다시피 크로스브라우징 문제때문에 Ajax 를 이용하여 비동기 멀티 파일 업로드를 구현했다. 훗....

구현시 몇가지 문제가 있었는데 첫번째 브라우저나 pc사양에 따라 다르겠지만 내 작업 노트북 기준( CPU : i7-4720 RAM : 8GB ) 인데

4메가 파일 100개 가량을 업로드 하니 브라우저가 그대로 프리징-_-;;; 이 발생해서 ( 뭐 당연한 얘기겠지만.... )  

50개 정도의 제한을 둘까 하다가 10개로 일단 제한을 걸어두었다. 

두번째는 Ajax 로 서버에 비동기 요청시 응답을 다 받기도 전에 다음 소스 코드가 수행이 되버려서 찾아보니 XmlHttpRequest 객체 

open(); 메서드의 세번째 파라미터 예 ) xhr.open("POST",URL,true); 를 xhr.open("POST",URL,false); 로 즉 false 로 변경하여 이를 해결하였다. 

추가로 ie-8 이하에서는 file폼에서 multiple 이 지원되지 않으므로 어쩔 수 없이 ie-8 일경우엔 activeX 다운로드 버튼이 보이도록 하였다.

아래는 소스 전문이다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    function ajaxUpload() {
        var objForm = document.f;
        var sf = objForm.file.files;
        if (objForm.file.value == "") {
            alert("파일을 선택해 주십시오.");
            return;
        } else {
            try {
                for (var i = 0; i < sf.length; i++) {
                    objForm.strFileName.value = sf[i].name.substr(sf[i].name.lastIndexOf("\\") + 1);
                    var formData = new FormData(objForm);
                    var xhr = initAjax();
                    xhr.open("POST", "mbox.auth.do?method=UploadMailProcess", false);
                    xhr.send(formData);
                }
            } catch (e) {
                console.log("Upload Error : "+e);
                alert("업로드 중 오류가 발생하였습니다.");
                return;
            } finally {
                alert("업로드가 완료되었습니다.");
                opener.location.reload();
                self.close();
            }
        }
    }
 
    function initAjax() { // 브라우저에 따른 AjaxObject 인스턴스 분기 처리
        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xmlhttp;
    }
 
    function limitFileChk() { //    파일 업로드 제한 
        var objForm = document.f;
        var sf = objForm.file.files;
        var fileLimit = sf.length;
        
        if (fileLimit > 10) {
            reloadDialog("eml 파일 업로드는 10개를 넘길 수 없습니다. zip 으로 업로드 
                               해주시기 바랍니다.", objForm);
            return;
        }
        if (!multiFileChk(objForm)) { // 다중 업로드시 확장자 체크
            return;
        }
    }
 
    function reloadDialog(msg, objForm) { // 팝업창 갱신
        alert(msg);
        objForm.file.value = null; //    firefox multi-file Form flush code
        location.reload();
    }
 
    function multiFileChk(objForm) {// 다중 업로드시 eml 외에 다른 확장자 올라가는것을 방지
        var sf = objForm.file.files;
        if (sf.length == 1 && sf[0].name.lastIndexOf(".zip") != -1) // .zip 은 한개만 업로드가능
            return true;
        for (var i = 0; i < sf.length; i++) {
            if (sf[i].name.lastIndexOf(".eml") < 0) {
                reloadDialog("다중 업로드는 .eml 파일만 지원합니다.", objForm);
                return false;
            }
        }
        return true;
    }


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    <form name="f" method="post" enctype="multipart/form-data">
        <input type="hidden" name="strFileName" value="">
        <table class="h2">
            <tr>
                <td><img src="/images_std/kor/bullet/arrow_pop.gif" align="top" />파일 업로드</td>
            </tr>
        </table>
        <div class="k_puAdmin_box">
            <table>
                <tr>
                    <td width="80" align="right"><strong>파일 선택</strong></td>
                    <td><input name="file" type="file" style="width: 350px;"
                             onchange="limitFileChk();" multiple/></td>
                </tr>
            </table>
        </div>
        <div style="text-align: center">
            <a href="javascript:ajaxUpload()"><img src="/images/kor/btn/popup_confirm.gif" /></a>
             &nbsp;
            <a href="javascript:window.close()"><img src="/images/kor/btn/popup_close.gif" /></a>
        </div>
    </form>


728x90
반응형

+ Recent posts