프론트엔드/React&JS
이미지를 서버에 전송해보자. (feat. FormData, async/await)
정예지
2022. 9. 2. 20:23
상품을 등록할 때 이미지도 서버에 전송해야하는데, 어떻게 해도 제대로 보내지지 않아서 엄청난 삽질을 했다.
1. 내가 한 어이없는 실수
// 미리보기 이미지
const handleImageInput = (e) => {
setPreview(URL.createObjectURL(e.target.files[0]));
};
이건 이미지 미리보기를 구현한건데 이 값을 그대로 보내려고 했다…
blob:http://주소/cb21c13b-1944-42ad-8aa4-94611177989a
이렇게 나와서 또 다른 실수를 하고야 마는데 …
앞에 blob:을 자르고 보내려고 한다 🤦♀️ (당연히 보내질리가…)
뭔가 FormData 를 사용해야하는 것은 알겠는데 … 명확하게 어떻게 사용해야할지 몰라서 굉장히 많은 방황을 했다.
2. 해결 방법
우선 API를 살펴보니 이미지를 따로 업로드하는 API가 있었다!
우선 폼제출 전에 이미지 데이터를 받아와서 폼제출을 완료하면 될 것 같다는 생각이 들었다.
// 이미지 업로드
const uploadImage = async () => {
let formData = new FormData(); // FormData 생성
const imgFile = inpRef.current.files; // 이미지 파일 가져오기
const file = imgFile[0]; // 이미지 파일이 한개라 0번 인덱스에 접근해 값 가져오기
formData.append('image', file); // image라는 키에 file이라는 값 넣기
const res = await axios.post( // await에 넘겨서 완료 될 때까지 기다리기
'<https://주소/image/uploadfile>',
formData
);
const imgUrl = `https://주소/${res.data.filename}`;
// 보낸 이미지 파일 데이터 받아서 저장
return imgUrl;
};
- 폼 제출 전에 실행해야하니 async function으로 비동기 함수를 정의해준다.
- file을 key/value 로 보낼 것이기 때문에 new FormData()로 FormData를 생성해준다.
- 이미지 파일에 접근해 값 가져오기
- FormData에 key, value 넣어주기
- await으로 이미지 파일이름 받아오기
// 상품등록 데이터 전송
const createProduct = async (e) => {
e.preventDefault();
if (state) {
// 추후에 로그인 기능 구현되면 삭제. 일회성 토큰
const url = '<https://주소.co.kr>';
const getToken = localStorage.getItem('token');
const res = uploadImage();
try {
await axios.post(
`${url}/product`,
{
product: {
itemName: name,
price: parseInt(
price
.split(',')
.reduce((curr, acc) => curr + acc, '')
),
link: link,
itemImage: await res, // 이미지 파일 데이터 받아오기
},
},
{
headers: {
'Authorization': `Bearer ${getToken}`,
'Content-type': 'application/json',
},
}
);
navigate('/myprofile');
} catch (error) {
console.log(error);
}
}
};
- 폼을 제출하는 함수에서 비동기로 먼저 const res = uploadImage(); 를 실행해 이미지 파일 데이터를 받아온다.
- itemImage에 이미지 파일 데이터를 받아오고 난 뒤 폼이 제출 되도록 한다.
이런 식으로 해결 완료!
참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/ko/docs/Web/API/FormData/FormData