인스타그램 클론코딩 프로젝트 진행 중 클라이언트에서 백엔드로 이미지를 전송하려면 FormData로 보내야한다는 것을 알게 되었다.
클라이언트와 서버 간 통신은 HTTP 메시지를 통해 이루어지는데, 이미지 파일 또한 문자열로 이루어져 있으므로, 이미지 파일을 jpg등의 파일 자체가 아닌 문자열로 생성하여 HTTP Request body에 담아 서버로 전송한다.
파일 업로드를 구현할 때,
클라이언트는 Content-Type 속성을 multipart/form-data
로 지정되고 정해진 형식에 따라 HTTP 메시지를 인코딩해서 전송한다.
서버는 multipart message에 대해 각 파트별로 분리하여 개별 파일의 정보를 얻게 된다.
Form 에서 이미지와 텍스트 등을 함께 전송하기 위한 목적으로 FormData를 사용한다.
multipart 타입은 일반적으로 다른 MIME 타입을 지닌 개별적인 파트로 나누어지는 문서의 카테고리를 가리키며, 즉 합성된 문서를 나타내는 방식이라고 볼 수 있다.
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
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