티스토리 뷰

화면단의 데이터를 백엔드로 넘기는 방법 중에서 대표적인 방법이 form 태그를 사용하는 것이다. 입력받은 데이터를 가공없이 submit만 해주면 되기 때문에 편하기도 하다. 하지만 데이터에 파일이 추가되는 경우 form 태그를 사용하기에 애매해지는 경우가 있다. 파일을 하나씩 선택하는 경우는 문제가 없는데 여러 파일을 한번에 선택하게 하는 경우이다.

 

1
2
3
4
// 파일 선택창에서 하나의 파일만 선택 가능
<input name="files" id="fileupload" type="file" />
// 파일 선택창에서 여러개의 파일을 한번에 
<input name="files" id="fileupload" type="file" multiple />

 

사실 여러개의 파일을 선택하는 것 까지는 크게 이상이 없다. 이 파일을 삭제하려고 할 때 문제가 발생한다. 파일은 속성이 readonly이기 때문에 추가, 변경이 불가능하다. 만약에 파일을 삭제하려고 한다면 선택적으로 삭제할 수 없고 추가했던 모든 파일을 모두 삭제해야 한다. 하지만 요구사항이 그렇게 단순하면 개발자는 참 편하겠지.....

 

FormData를 사용하여 이 문제를 해결하려고 한다. FormData에 대한 설명은 아래와 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
FormData 인터페이스는 XMLHttpRequest.send()로 쉽게 보내질 수 있는 폼 field와 
그 값들로 나타나는 key/value쌍들을 쉽게 만들 수 있는 방법을 제공한다. 
만약에 인코딩 타입이 "multipart/form-data"로 설정이 되어 있으면 폼이 사용하는 것과 같은 포맷으로 사용한다.
 
// form 태그가 있는 경우
// form 태그가 html에 있는경우(여기서는 create_form이라는 id로 세팅된 form 태그) 
// FormData 생성자 함수에 인자로 넘겨서 input 태그에 있는 데이터들을 따로 세팅하지 않아도 사용할 수 있다.
var createForm = document.getElementById("create_form");
var formData = new FormData(createForm );
 
// form 태그가 없는 경우
var formData = new FormData();
 

 

 

파일 태그가 있는 html 부분

 

1
2
3
4
// 파일 input 태그가 아래와 같이 선언되어 있고
<input name="files" id="fileupload" type="file" multiple />
// 추가된 파일 이름과 삭제할 수 있는 버튼이 추가 되는곳은 아래와 같이 선언되어 있다.
<div id="fileList"></div>
 

 

 

 

 

 

파일을 추가 삭제하는 부분의 javascript

 

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
// 파일이 추가되는 순간 addFiles 함수가 실행된다.
$(document).ready(function() {
    $("#fileupload").on("change", addFiles);
});
 
var filesTempArr = [];
// 파일 추가
function addFiles(e) {
    var files = e.target.files;
    var filesArr = Array.prototype.slice.call(files);
    var filesArrLen = filesArr.length;
    var filesTempArrLen = filesTempArr.length;
    forvar i=0; i<filesArrLen; i++ ) {
        filesTempArr.push(filesArr[i]);
        $("#fileList").append("<div>" + filesArr[i].name + "<img src=\"/images/deleteImage.png\" onclick=\"deleteFile(event, " + (filesTempArrLen+i)+ ");\"></div>");
    }
    $(this).val('');
}
// 파일 삭제
function deleteFile (eventParam, orderParam) {
    filesTempArr.splice(orderParam, 1);
    var innerHtmlTemp = "";
    var filesTempArrLen = filesTempArr.length;
    for(var i=0; i<filesTempArrLen; i++) {
        innerHtmlTemp += "<div>" + filesTempArr[i].name + "<img src=\"/images/deleteImage.png\" onclick=\"deleteFile(event, " + i + ");\"></div>"
    }
    $("#fileList").html(innerHtmlTemp);
}
 

 

데이터를 전송하는 부분의 javascript

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
var formData = new FormData();
 
// 파일 데이터
for(var i=0, filesTempArrLen = filesTempArr.length; i<filesTempArrLen; i++) {
   formData.append("files", filesTempArr[i]);
}
 
formData.append("testData1""A");
formData.append("testData1""B");
formData.append("testData1""C");
 
$.ajax({
    type : "POST",
    url : "서블릿 URL",
    data : formData,
    processData: false,
    contentType: false,
    success : function(data) {
        if(data.result){
            alert("Success");
        }else{
            alert(data.result);
        }
        
    },
    err : function(err) {
        alert(err.status);
    }
});
 

 

위와 같이 작성하면 form 태그로 submit 하는거와 동일한 동작을 하면서 파일추가와 삭제를 자유롭게 할 수 있다.

 

 

이 API를 사용하려면 최신의 브라우저를 사용해야 한다.

 

 

 

참고사이트

 

 

댓글