-
[파일업로드] Ajax 방식파일업로드 2016. 9. 11. 16:05
파일업로드 Ajax 방식의 핵심은 FormData 라는 브라우저에서 지원하는 클래스이다.
FormData 는 <form> 과 같은 효과를 가져다주는 key/value 가 저장되는 객체이다. <form> 태그처럼 데이터를 처리할 수 있게 해준다. 이를 XHR 에 실어서 서버에 보내면 마치 <form> 이 전송된 것과 같은 효과를 가져다 준다.
IE 에서는 10 부터 지원한다고 한다. (참고)
사용자가 선택한 File 을 아래와 같이 FormData 에 추가할 수 있다.
검색해보니 좋은 예제가 있어 복사했다. (출처는 여기)
1234567891011121314151617181920$('drag-target-selector').on('drop', function(event) {//stop the browser from opening the fileevent.preventDefault();//Now we need to get the files that were dropped//The normal method would be to use event.dataTransfer.files//but as jquery creates its own event object you ave to access//the browser even through originalEvent. which looks like thisvar files = event.originalEvent.dataTransfer.files;//Use FormData to send the filesvar formData = new FormData();//append the files to the formData object//if you are using multiple attribute you would loop through//but for this example i will skip thatformData.append('files', files[0]);}cs 사용자가 파일을 Drag & Drop 했을 때의 처리에 대한 내용이다.
브라우저에 어떤 파일을 drop 하면 브라우저 기본 동작이 실행된다. 이미지를 drop 하면 바로 표시되고 pdf 파일의 경우도 각 브라우저의 pdf viewer 로 브라우저 내에서 문서를 열어 보여준다. 이를 방지하기 위해 preventDefault() 를 호출한다.
그 다음 이벤트에서 file 정보를 받아온다. drag & drop 동작에서 파일 정보는 DataTransfer 라는 객체를 통해 얻어올 수 있다. 스펙은 여기에 있는데, 여러가지 기능을 제공하고 있다. files 라는 프로퍼티를 참고하자. 이것도 IE 는 10 이상에서 지원된다고 한다.
이렇게 얻은 파일 정보를 formData.append() 를 통해 key/value 형식으로 넣는다. 최종적으로 jQuery의 Ajax API를 통해 전송하면 된다.
12345678910$.ajax({url: '/uploadAjax',data: formData,dataType: 'text',processData: false,contentType: false,type: 'POST',success: function(data) {});cs 파라미터 중 dataType, processData, contentType 을 보자.
dataType 은 내가 보내는 데이터의 타입이 아니고 서버가 응답(response)할 때 보내줄 데이터의 타입이다. 이는 success function 에 전달될 argument 의 형태를 지정하는데 사용된다고 한다. (참고)
processData 관련하여, 일반적으로 서버에 전달되는 데이터는 query string 이라는 형태로 전달된다. (아래 빨간 부분)
ex) http://example.com/over/there?title=Main_page&action=raw
data 파라미터로 전달된 데이터를 jQuery 내부적으로 query string 으로 만드는데, 파일 전송의 경우 이를 하지 않아야 하고 이를 설정하는 것이 processData: false 이다.
contentType 은 default 값이 "application/x-www-form-urlencoded; charset=UTF-8" 인데, "multipart/form-data" 로 전송이 되게 false 로 넣어준다. false 로 넣어주는 것이 언뜻 이해가 안되서 false 말고 "multipart/form-data" 를 넣어봤는데 boundary string 이 안들어가게 되어 제대로 동작하지 않았다.
파일을 전송해보면 content-type header 가 아래와 같이 설정된다.
boundary string 은 전송되는 데이터의 영역을 구분해주는 구분자로 브라우저에서 넣어주는 건데, contentType을 명시적을 설정할 경우 boundary string 을 overwrite 하게 되는게 아닌가 한다.
'파일업로드' 카테고리의 다른 글
[파일업로드] 업로드한 파일 다운로드 처리 (0) 2016.09.12 [파일업로드] 서버에서의 처리 (0) 2016.09.12 [파일업로드] <form> 방식 (0) 2016.09.11 [파일업로드] MIME (0) 2016.09.10