[React] 서버에 form 보내기(1)

혜린·2022년 9월 15일
4

React

목록 보기
11/18
post-thumbnail

들어가며


해결한 점

사용자가 아이디, 이름, 비밀번호, 이미지 파일을 넣으면 서버에 해당 데이터를 함께 보내고 싶었어요. 네트워크 메서드인 fetch()를 사용해서요!

이미지 파일 전송이 문제라서 이미지 파일만 먼저 테스트했어요. 로그인, 회원가입 실습 때 텍스트만 보내봤지 이미지는 처음이라 굉장히 생소했던.. 하루종일 끙끙대다가 FormDataappend()로 이미지 파일을 넣을 때의 key값을 백엔드분과 일치시키니 FormData가 제대로 서버로 넘어가는걸 확인할 수 있었답니다~!🎉

서버에 보낸 FormData를 콘솔에 찍으면 다음과 같이 나와요. 이메일, 이름, 닉네임, 비밀번호, 프로필 이미지, 이렇게 5가지를 담아 보냈어요. 그리고 FormData를 콘솔에 찍어볼때는 console.log(FormData)와 같은 식으로 하면 빈 객체만 나와요. for문을 사용해서 콘솔을 찍어줘야한다는 점-!까지 배울 수 있었습니다🤗


어떻게 했냐면...

회원가입 버튼을 눌렀을 때 onClick이벤트로 아래의 함수가 실행됩니다. new FormData()FormData객체를 생성했고, 사용자가 입력한 email, name, nickname, password, 이미지파일을 append()메소드로 넣어주었어요. 그리고 Request메시지의 본문(body)에 생성한 FormData객체를 넣어주었어요.

// 회원가입 버튼의 onClick이벤트
const checkSignUp = (e) => {
  e.preventDefault();
  const formData = new FormData();
  formData.append("email", email);
  formData.append("name", name);
  formData.append("nickname", nickname);
  formData.append("password", password);
  formData.append("profileImg", imgRef.current.files[0]);

  fetch("API 주소", {
    method: "POST",
    headers: {
      "Content-Type": "multipart/form-data",
    },
    body: formData,
  })
    .then((response) => {
      if (response.ok === true) {
        return response.json();
      }
      throw new Error("에러 발생!");
    })
    .catch((error) => {
      alert(error);
    })
    .then((data) => {
      console.log(data);
    });
};

개선해야 할 점

formData<form>태그에 대해 공부해보니 제가 작성한 코드보다 더 효율적인 방법이 있는 것 같아 수정해보려고해요. 저는 HTML form태그가 있음에도 formData객체에 append로 필드를 추가해주는 방식으로 코드를 짰어요. 근데 HTML form 태그가 있으면 해당 폼만 바로 formData객체에 넘겨줄 수 있더라구요. 리팩토링에 성공하면 다음 포스팅 때 비교해볼 예정이에요!



FormData


FormData란?

FormDatafetch()와 같은 네트워크 메서드를 통해 HTML 폼(form)을 보내요. 폼(form)을 쉽게 보내도록 도와주는 객체죠.

// FormData 생성하기
const formData  = new FormData();

사용방법

  1. HTML form이 있을 때
    : HTML form을 직접 넘겨 new FormData(form)로 만들 수 있어요.
    <!-- HTML form -->
    <form id="formElem">
      <input type="text" name="name" value="hyerin">
      <input type="text" name="surname" value="joo">
      <input type="submit">
    </form>
     // HTML form 직접 넘기기
     fetch('API 주소', {
     	method: 'POST',
     	body: new FormData(formElem)
     });

  1. HTML form이 없을 때
    : formData.append(name, value)와 같이 메서드로 직접 namevalue를 가진 폼 필드를 추가해 만들 수도 있어요.

    let formData = new FormData();
    formData.append('key1', 'value1');
    formData.append('key2', 'value2');
    
    fetch('API 주소', {
          method: 'POST',
          body: formData;
    });

특징

  • fetch()와 같은 네트워크 메서드가 FormData 객체를 본문(Body)으로 받는다.
  • Content-Type 속성은 multipart/form-data로 지정되어 전송된다.
  • 파일 있는 폼 전송 시, HTTP 요청 메시지의 Content-Type속성은 항상 multipart/form-data.

콘솔 확인법

콘솔로 FormData에 값이 제대로 담긴건지 확인하고 싶을 때, 저는 처음에 아무것도 모르고 console.log(FormData)를 남발했어요. 계속 빈 객체만 콘솔에 찍혔답니다. 반복문을 사용해야 확인할 수 있다는걸 알게됐어요.

const formData = new FormData();
for (const keyValue of formData) console.log(keyValue);



<form>태그


🤔 서버 관점에선 FormData를 사용한 방식과 일반 폼 전송 방식(<form>)에 차이가 없다고 해요. 심지어 HTTP 요청 메시지의 본문(Body)에 FormData를 보낼 때, 헤더의 Content-Type속성은 <form>태그의 enctype 속성과 관련있다는 것을 알게 됐답니다. 그래서 <form>태그의 enctype은 무엇인지 정리하게 됐어요.


enctype 속성

<form>태그의 enctype 속성은 폼 데이터가 서버로 제출될 때 해당 데이터가 인코딩되는 방법을 명시해요. 이 속성은 <form>요소의 method 속성값이 POST인 경우에만 사용할 수 있어요.

<form enctype="속성값">

📜 인코딩(Encoding)이란?

  • 사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 신호로 만드는 것입니다. 컴퓨터는 모든 정보를 0과 1인 바이너리, 즉 숫자로 저장합니다.
  • 반대로 디코딩은 0과 1로 구성된 바이너리 데이터를 다시 문자로 복구하는 것입니다.

속성값

  1. application/x-www-form-urlencoded

    • 기본값
    • 모든 문자들이 서버로 보내기 전에 인코딩됨
  2. multipart/form-data

    • 모든 문자를 인코딩하지 않음
    • 파일이나 이미지 전송할 때 주로 사용
  3. text/plain



HTTP 요청 메시지의 Content-Type


폼(form) 데이터가 서버로 제출될 때 해당 데이터가 인코딩되는 방법까지 알았으니, 이제 HTTP요청 메시지의 Content-Type을 어떻게 작성해야할 지 알 수 있어요. 요청(Request) 메시지의 헤더에서 서버에게 어떤 유형의 데이터가 실제 전송되었는지를 Content-Type을 통해 알려줄 수 있답니다.

HTML 양식은 앞서 <form>태그의 enctype 속성값에서 본 것과 같이 세 가지의 인코딩 방법을 제공하죠. <input type="file">요소가 포함된 경우에는 multipart/form-data를 사용해요.

// 요청 메시지의 헤더
headers: {
	"Content-Type" : "multipart/form-data",
}



참고


profile
FE Developer

0개의 댓글