[React] File과 JSON 동시에 주고 받기 (Multipart/form-data)

2023. 2. 12. 01:01·🍞 FrontEnd/React

파일은 이미 흔히 Multipart/form-data로 주고 받고 있다.

관건은 JSON 데이터를 Multipart/form-data로 보내는 것이다.

 

파일 같은 경우, formData를 생성해 바로 append 해주면 되지만, 

JSON 데이터 같은 경우는 JSON.stringify를 사용해 string 형식으로 보내줘야 한다.

FormData.append()의 파라미터 타입을 보면, value에는 string과 Blob(binary large object) 타입만 전달할 수 있다.
따라서 아래에서 uploader 객체를 append 할 때 바로 넣지 않고 JSON.stringify()로 문자열로 변환하여 전달했다.

 

아래처럼 파일을 업로드하여 요청을 보내면 서버에서 JSON 데이터를 함께 전달받을 수 있다.

// App.tsx
import React, {useCallback, useState} from 'react';
import axios from 'axios';

interface Uploader {
    name: string;
}

function App() {
   (...)

    const handleClick = useCallback(async () => {
        if (!file) return;

        const formData = new FormData();
        await formData.append('file', file);
        const uploader: Uploader = {name: 'huewilliams'};
        await formData.append('uploader', JSON.stringify(uploader));

        const res = await axios.post(
            'http://localhost:4000/file/upload',
            formData,
            {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            }
        );
        if (res.status === 201) console.log(res.data);
    }, [file]);

   (...)
}

export default App;

 

🔥 그러나, 서버가 Spring일 경우?

Express와는 다르게 동작하니 주의해야 한다. 기존에 했던 것 처럼 JSON.stringify()만 적용하여 보낼경우 415 Unsupported Media Type Error가 발생한다. 정확히는 아래에 나와있는 application/octet-stream 녀석 때문이다.

appication/octet-stream
8비트 단위의 바이너리 데이터를 의미한다.

 

위 같은 문제가 발생한 이유는 서버에서는 json 타입으로 rq를 받는 것으로 정의했는데, 클라이언트에서 string으로 변환해서 보냈기 때문에 에러가 발생한 것이다.


해결법은 다음과 같다.

formdata에 append할 때 JSON.stringify로 생성한 문자열을 Blob으로 만들고 그 타입을 application/json으로 지정해주면 된다.

// 415 Error
await formData.append('uploader', JSON.stringify(uploader));

// Good 😋
const uploaderString = JSON.stringify(uploader);
await formData.append('uploader', newBlob([uploaderString], {type: 'application/json'}));

 

이번 오류을 마주하면서 꽤 다양한 Content-Type을 조사하고 다뤄본 것 같다. 사실 문제에 마주쳤을 때 마지막 부분의 해결법만 알면 구현은 할 수 있지만, 여기까지 도달한 과정과 이것을 통해 배운 지식들이 더 값진 것 같다.

 

 

저작자표시 (새창열림)

'🍞 FrontEnd > React' 카테고리의 다른 글

[WebSocket, stompjs] 채팅 기능 client null 값  (0) 2023.08.14
[React] useMutation를 활용한 데이터 생성, 수정, 삭제  (0) 2023.02.06
[React] 리페칭(Re-fetching)에 대해서  (0) 2023.02.06
[React] Recoil-persist 사용해보기  (0) 2023.02.03
[React] CORS 에러 해결하기  (0) 2023.01.30
'🍞 FrontEnd/React' 카테고리의 다른 글
  • [WebSocket, stompjs] 채팅 기능 client null 값
  • [React] useMutation를 활용한 데이터 생성, 수정, 삭제
  • [React] 리페칭(Re-fetching)에 대해서
  • [React] Recoil-persist 사용해보기
박빵이
박빵이
2025년에도 갓생살기
  • 박빵이
    기억보다 기록
    박빵이
  • 전체
    오늘
    어제
    • 분류 전체보기 (337)
      • 🍞 FrontEnd (97)
        • HTML+CSS (4)
        • JavaScript (17)
        • TypeScript (4)
        • React (52)
        • Next.js (2)
        • Android (15)
      • 🍞 BackEnd (24)
        • Java (15)
        • Node.js (6)
        • Spring (1)
      • 🍞 Cloud & Infra (0)
        • AWS SAA (0)
        • Microsoft Azure (0)
      • 🍞 Algorithm (147)
        • C++ (4)
        • Baekjoon (41)
        • Programmers (97)
      • 🍞 Computer Science (18)
        • 운영체제 (1)
        • 데이터 통신 (6)
        • 네트워크 (6)
        • 데이터베이스 (1)
      • 🍞 대외활동 & 부트캠프 (42)
        • 삼성 청년 SW 아카데미 (1)
        • LG유플러스 유레카 (0)
        • 한국대학생IT경영학회 (1)
        • IT연합동아리 UMC (17)
        • 길벗 블로깅 멘토 (18)
        • IT연합동아리 피로그래밍 (3)
        • 개발 컨퍼런스 (2)
  • 블로그 메뉴

    • Admin
  • 링크

    • GitHub
  • 인기 글

  • 태그

    map
    JavaScript
    C++
    안드로이드
    코딩자율학습
    umc
    level1
    길벗 블로깅 멘토링
    Android
    level2
    react
    알고리즘
    길벗 블로깅 멘토
    Java
    프로그래머스
    유니온파인드
    위상정렬
    백준
    Front
    코틀린
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
박빵이
[React] File과 JSON 동시에 주고 받기 (Multipart/form-data)
상단으로

티스토리툴바