ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [파일업로드] Ajax 방식
    파일업로드 2016. 9. 11. 16:05

    파일업로드 Ajax 방식의 핵심은 FormData 라는 브라우저에서 지원하는 클래스이다. 

     

    FormData 는 <form> 과 같은 효과를 가져다주는 key/value 가 저장되는 객체이다. <form> 태그처럼 데이터를 처리할 수 있게 해준다. 이를 XHR 에 실어서 서버에 보내면 마치 <form> 이 전송된 것과 같은 효과를 가져다 준다.

     

    IE 에서는 10 부터 지원한다고 한다. (참고)

     

    사용자가 선택한 File 을 아래와 같이 FormData 에 추가할 수 있다.

    검색해보니 좋은 예제가 있어 복사했다. (출처는 여기)

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $('drag-target-selector').on('drop'function(event) {
     
     //stop the browser from opening the file
     event.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 this
     var files = event.originalEvent.dataTransfer.files;
     
     //Use FormData to send the files
     var 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 that
     formData.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를 통해 전송하면 된다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            $.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 가 아래와 같이 설정된다.

     

    1. Content-Type:
      multipart/form-data; boundary=----WebKitFormBoundarybuOGBs9coioS5Kb9

     

    boundary string 은 전송되는 데이터의 영역을 구분해주는 구분자로 브라우저에서 넣어주는 건데, contentType을 명시적을 설정할 경우 boundary string 을 overwrite 하게 되는게 아닌가 한다.

     

Designed by Tistory.