티스토리 뷰

FromData란 ajax로 폼 전송을 가능하게 해주는 FormData 객체입니다.

보통은 Ajax로 폼(form 태그) 전송을 할 일이 거의 없습니다.

주로 JSON 구조로 "KEY-VALUE" (키와 값) 구조로 데이터를 전송합니다.

 

하지만,

form전송이 필요한 경우가 있는데, 이미지를 ajax로 업로드할 때 필요합니다.

이미지는 base64, buffer, 2진 data 형식으로 서버로 전송해도 됩니다.

 

하지만 추천 드리는 방법은 input[type=file]을 사용해 form(폼)을 통해서 업로드를 하는 것 입니다.

보통, form을 제출하면 action 속성에 의해 지정한 페이지로 이동하면서 데이터를 전송합니다.

ajax반대로 제출 버튼을 누르면 기본 폼 동작은 e.preventDefault()  로 멈추고, 페이지 전환 없이 데이터를 전송합니다.

 

페이지 전환 없이 폼 데이터를 제출 하고 싶을 때 바로 FormData 객체를 사용합니다.

 

FormData 객체란 ?

- " window.FormData "에 위치합니다.

//html에 form 태그가 있으면 제이쿼리나 자바스크립트로 가져옵니다
var formData1 =new formData($("#form Id")); //제이쿼리인 경우
var formData2 =new formData(document.getElementById("form Id")); //자바스크립트로 가져 올 경우



//html에 form 태그가 없을 때 
//new FromData()로 새로운 객체 생성
var formData = new FormData();
formData.append('name','hyemin');
formData.append('item','hi');
formData.append('item','hello');

 

append() 메소드로 key-value 값을 하나씩 추가해주면 됩니다.

 

같은 key를 가진 값을 여러 개 넣을 수 있습니다.

(덮어씌워지지 않고 추가가 됩니다.)

참고로 값은 "문자열"로 자동 변환 됩니다.

 

주의 !! 

 

* 숫자를 넣어도 문자열이 되고, 배열을 넣어도 콤마로 구분한 문자열이 됩니다. 객체는 넣으면 무시가 됩니다 !!!

 

기존에 form이 존재하는 경우에는 

var formData = new FormData(document.getElementById('폼 아이디'));

이런식으로 넣어주면 됩니다.

 

formData에 값이 들어있는지 확인하는 방법

// 값이 boolean type으로 반환됩니다.
formData.has('item'); // true 
fromData.has('money'); //false

//이때는, 값의 첫 번째 값이 반환됩니다.
formData.get('item'); // hi 

//값을 모두 가져올 때 배열 형식으로 가져옵ㄴ디ㅏ.
formData.getAll('item'); // ['hi','hello']

 

메소드 별 특징

has() : has메소드는 해당하는 key가 존재하는 지 확인할 수 있습니다.

get() : get메소드로 직접 가져올 수 있습니다.

( *get은 처음 저장한 값 하나만 불러옵니다.)

getAll() : 해당 key에 매칭되는 value값을 모두 배열로 반환합니다.

 

 

 

| Iterator(반복자)를 사용한 formData 값 가져오기

//key 값을 가져옵니다.
var keys = formData.keys();
keys.next(); // { done : false , value : 'name' }
keys.next();// { done : false , value : 'item' }
keys.next();// { done : false , value : 'item' }
keys.next();// { done : true , value : 'undefined' }


//values 값을 가져옵니다.
var values = formData.values();
values.next();// {done : false, value : 'hyemin'}
values.next();// {done : false, value : 'hi'}
values.next();// {done : false, value : 'hello'}
values.next();// {done : true, value : undefined}



var entries = formData.entries();
entries.next(); // {done : false, value =[ 'name','hyemin'] }
entries.next(); // {done : false, value =[ 'item','hi'] }
entries.next(); // {done : false, value =[ 'item','hello'] }
entries.next(); // {done : true, value = undefined }

(* IE에서는 안되는 단점이 존재합니다)

 

FormData의 key나 value, 또는 key와 value 값 모두를 쉽게 보여줄 수 있습니다.

반복문에 사용하면 좋습니다.

 

| formData에 들어있는 값 지우기 delete()

formData.append( 'test', ['hi','hyemin'] );
formData.get('test'); // hi,hyemin

formData.delete('test');

formData.get('test'); // null값이 들어갑니다.
formData.set('item','test2');
formData.getAll('item); // ['test2']

 

| formData의 Set과 append()의 차이점

- append와 비슷한 set 메소드는 set도 추가를 해주기는 하지만, 기존 key가 있으면 그 key값을 모두 덮어씌워버립니다.

 

 

| formData에 이미지 담기

var formData = new FormData();
formData.append('img',document.getElementById('file input').files[0]);

- 이렇게 선언하면, 'img'라는 key값으로 input 값에 담긴 file이 value값으로 들어가게 됩니다.

 

( 파일이 여러 개면 반복문으로 append를 하면 됩니다. )

 

주의 !!

 여러 개를 append할 때 항상 "key" 값은 같아야 여러 파일이 같은 키로 업로드 됩니다. !!

(set을 이용하면 덮어씌워지기 때문에 append를 사용합시다 !!! ) 

또한, form의 속성중 (파일 전송 시) enctype이 반드시 'multipart/form-data'형 이어여만 합니다.

 

 

HTTP Header

- HTTP 헤더는 사용자의 브라우저와 웹 서버가 요청 OR 응답으로 부가적인 정보를 전송할 수 있도록 해줍니다.

폼에 입력한 enctype이란,  HTTP 헤더의 내용 중 Content-type을 수정하는 것 입니다.

 

F12(개발자도구)를 활용하여 보는 방법

Content-type의 종류로는 다양한 type들이 있지만 브라우저가 post 전송할 때 지원해야 하는 타입은 다음과 같습니다

- application/x-www-form-urlencoded

- mulipart/form-data

 

| application/x-www-form-urlencoded

 

일반적인 브라우저에 폼에 enctype을 별도로 지정하지 않을 때 이 타입으로 전송됩니다.

(우리가 전송하려는 데이터가 영,숫자가 아닌 경우 3바이트로 표현하기 때문에 바이너리 파일을 전송할 경우 페이로드를 3배로 만들기에 무척 비효율적입니다.)

 

그렇기 때문에 브라우저에서 파일을 전송할 때 application/x-www-form-urlencoded 는 적합하지 않습니다.

 

| multipart/form-data

영숫자가 아닌 문자는 3바이트로 표현해야 하는 application/x-www-form-urlencoded에 비해 페이로드에 많은 옵션을 제공하기 때문입니다.

덕분에 바이너리 데이터를 효율적으로 전송할 수 있으나 웹에서 많이 사용되는 텍스트로만 이루어진 POST 전송은 오히려 MIME 헤더가 추가되기 때문에 오버 헤드가 발생됩니다.

 

제이쿼리로 ajax 파일 업로드 시 유의사항

 

$.ajax({

	contentType : false,
    processData : false,
    data : formData
    url :
    type : 'post'
    success :  . . . 

})

1. ajax로 multipart 방식으로 보낼 때, processData는 일반적으로 서버에 전달되는 data는 query String 형태로 전달되어 집니다.

data 파라미터로 전달된 데이터는 jQuery 내부적으로 쿼리스트링으로 만들어 보내는데, 파일전송에는 이를 피해야함으로

false로 설정해줍니다.

 

2. contentTypedefault 값이 "application/x-www-form = urlencoded; charset = UTF-8" 이므로, 보내줄 때

multipart/form-data로 전송해야 하기 때문에 false로 설정해줍니다.

 

 

 

정리하자면, 파일 전송 시 enctype은 multipart/form-data로 text값으로 이루어진 영,숫자는 application/x-www-form-urlencoded type으로 보내는게 효율적입니다.

 

 

실시간 베스트 글

혹시 국비지원이나 사설학원 (패스트 캠퍼스 등) 다니는 중이신가요?

 

현직 5년차가 직접 겪은 국비지원 패스트캠퍼스 후기 보러가기

 

국비지원 패스트캠퍼스 후기 현직 5년차 개발자가 알려주는 코딩학원 현실

국비지원 패스트캠퍼스 후기 현직 개발자가 경험한 코딩학원 선택 기준 및 현실에 대해 알려드립니다. 이런 분들은 절대 수업 듣지도 마세요.