axios formData로 s3에 이미지 업로드하기

jellyjw·2023년 3월 21일
1
post-thumbnail

이미지 업로드 과정

유저가 업로드하는 프로필 사진이나, 봉사등록 이미지를 S3에 올려 받아오기로 했다.

1. 유저 이미지 업로드시 axios를 이용해 서버로 이미지 전송

백엔드에서 S3에 이미지 업로드 되는 API를 만들어 둬서, 그 주소로 axios를 이용해 POST 요청을 보냈다.
(aws-sdk 를 이용해 클라이언트에서 직접 보내는 방법도 있지만 AWS access key를 직접 이용해야 하기 때문에 보안이슈가 있어 잘 사용되는 방법은 아니라고 한다.)

이 때 axios headers를 "multipart/form-data" 으로 설정해 form-data 로 보내줘야 한다. 이게 핵심!

	const formData = new FormData();
	formData.append("profile", fileSrc); // key, value
	axios({
		headers: {
			"Content-Type": "multipart/form-data",
		},
		url: "s3으로 업로드 가능한 url 입력",
		method: "POST",
		data: formData,
	})
		.then((res) => setImageUrl(res.data)) // 미리 만들어둔 state
		.catch((err) => console.log(err));
	}

append 하는 부분에서 첫번째 인자인 profilekey, 두번째 인자인 fileSrcvalue 이다.
API에 S3 버킷 객체 내의 이미지가 담길 폴더명으로 key가 설정되어 있어서 profile로 변경해주었고, 정상적으로 ImageUrl이 등록되었다.

2~3. S3 버킷에 이미지 업로드 후 url 응답


요청에 성공한다면 서버에서는 우리가 보낸 이미지를 S3 버킷에 업로드하고, S3 내에 업로드 된 이미지 Url을 response로 보내준다.

4. response로 받은 url을 서버에 등록

이제 우리는 S3 버킷에 올라간 이미지 URL을 서버로부터 응답받게 된다.
이 값을 state 에 저장해 봉사등록 정보를 보낼때 다시 보내주면, 정상적으로 유저에게 뿌려줄 데이터에 s3에 등록된 이미지 url을 등록할 수 있다.


어려웠던 점

처음에는 유저가 이미지를 업로드할때마다 서버로 딱 한번만 보내야 된다는 생각에, useEffect를 이용해서

useEffect(() => {
	const formData = new FormData();
	formData.append("profile", fileSrc);
	axios({
		headers: {
			"Content-Type": "multipart/form-data",
		},
		url: "",
		method: "POST",
		data: formData,
	})
		.then((res) => setImageUrl(res.data))
		.catch((err) => console.log(err));
	}
 }, [fileSrc]

이런식으로 작성해줬었는데, 유저가 input 필드를 입력하면서 컴포넌트가 리렌더링 될때마다 서버로 같은 요청이 계속 갔다.
결국 S3 객체에 같은 사진이 계속해서 쌓이게 되는 꼴이었다. ^_^..

useEffect나 useCallback을 이용할 필요 없이, 유저가 사진을 업로드하는 함수 내에 로직을 작성해줘서 말끔하게 한번만 업로드 되도록 문제를 해결했다.

profile
남는건 기록뿐👩🏻‍💻

0개의 댓글