파일은 이미 흔히 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을 조사하고 다뤄본 것 같다. 사실 문제에 마주쳤을 때 마지막 부분의 해결법만 알면 구현은 할 수 있지만, 여기까지 도달한 과정과 이것을 통해 배운 지식들이 더 값진 것 같다.
'🍞 Front-End > 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 |