-
이미지를 서버에 전송해보자. (feat. FormData, async/await)프론트엔드/React&JS 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
'프론트엔드 > React&JS' 카테고리의 다른 글
URL.createObjectURL() 로 이미지 미리보기(프리뷰)를 만들어보자! (리액트에서 사용) (0) 2022.09.19 여러개의 input 상태 관리하기 (0) 2022.09.19 styled-component를 사용해보자. (0) 2022.09.10 useState는 뭔가요? (0) 2022.09.09 React useParams에 대해 알아보자 (+ 현재 페이지 pathname 가져오기) (0) 2022.08.03