[week7 클론 코딩 프로젝트] FormData란?

G-NOTE·2022년 8월 21일
0

항해99

목록 보기
32/36

FormData란

인스타그램 클론코딩 프로젝트 진행 중 클라이언트에서 백엔드로 이미지를 전송하려면 FormData로 보내야한다는 것을 알게 되었다.

클라이언트와 서버 간 통신은 HTTP 메시지를 통해 이루어지는데, 이미지 파일 또한 문자열로 이루어져 있으므로, 이미지 파일을 jpg등의 파일 자체가 아닌 문자열로 생성하여 HTTP Request body에 담아 서버로 전송한다.

파일 업로드를 구현할 때,
클라이언트는 Content-Type 속성을 multipart/form-data로 지정되고 정해진 형식에 따라 HTTP 메시지를 인코딩해서 전송한다.
서버는 multipart message에 대해 각 파트별로 분리하여 개별 파일의 정보를 얻게 된다.

FormData 사용

Form 에서 이미지와 텍스트 등을 함께 전송하기 위한 목적으로 FormData를 사용한다.
multipart 타입은 일반적으로 다른 MIME 타입을 지닌 개별적인 파트로 나누어지는 문서의 카테고리를 가리키며, 즉 합성된 문서를 나타내는 방식이라고 볼 수 있다.

FormData console.log 찍기

formdata로 POST 요청을 보내기 전 console.log를 확인하려 했더니 이상한 객체가 나오는 문제가 있었다.

FormData 객체는 XMLHttpRequest 전송을 위해 설계된 특수한 객체로, 문자열화 할 수 없기 때문에 console.log로 출력되지 않는다고 한다. 따라서 POST 요청 전 내용을 확인하고 싶다면 아래와 같이 해야 한다.

// FormData key 
for (let key of formData.keys()) {
  console.log(key);
}
// FormData value 
for (let value of formData.values()) {
  console.log(value);
}

결과

image
image
content

File {
  path: "instagram_1440_05.jpg"
  preview: "blob:http://localhost:3000/d3ab8d12-c447-45d2-bab2-d25a0fab814e"
  lastModified: 1660883411554
  lastModifiedDate: Fri Aug 19 2022 13:30:11 GMT+0900 (한국 표준시) {}
  name: "instagram_1440_05.jpg"
  size: 201696
  type: "image/jpeg"
  webkitRelativePath: ""
}
File {
  path: "instagram_1440_04.jpg"
  preview: "blob:http://localhost:3000/c9e96c65-a710-4899-aa2b-993556cf219c"
  lastModified: 1660883811263
  lastModifiedDate: Fri Aug 19 2022 13:36:51 GMT+0900 (한국 표준시) {}
  name: "instagram_1440_04.jpg"
  size: 108117
  type: "image/jpeg"
  webkitRelativePath: ""
}
hello

Form onSubmit 이벤트핸들러 코드

  • 텍스트는 입력하지 않아도 되지만 사진은 반드시 한 장 이상 선택하도록 했다.
const onSubmitHandler = async () => {
    if (files.length === 0) {
      window.alert("사진을 1장 이상 선택해야 합니다.");
    } else {
      const formData = new FormData();

      files.map((file) => formData.append("image", file));
      formData.append(
        "dto",
        new Blob([JSON.stringify(text)], { type: "application/json" })
      );

      await dispatch(__postPosts(formData));
      await handleOpenModal();
    }
  };

참조

https://velog.io/@josworks27/formData-console.log
https://velog.io/@shin6403/HTTP-multipartform-data-%EB%9E%80
https://velog.io/@kyeongsoo5196/FormData%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8C%8C%EC%9D%BC-%EC%A0%84%EC%86%A1
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects#submitting_forms_and_uploading_files_via_ajax_without_formdata_objects

profile
FE Developer

0개의 댓글