오늘 처음으로 이미지 파일을 서버에 보내주게 됐는데, 그 과정에 대해 정리해보려 한다.
먼저 form의 input type은 file이어야 한다. 백엔드분들이 jpeg 형식의 이미지파일만 가능하다 하셔서 accept부분은 다음과 같이 설정했는데, png, jpg파일도 저부분에 써주기만 하면 가능하다. 자동으로 변환해주는것같기도 하다. jpg 파일을 업로드했는데 자동으로 jpeg가 돼 있었다.
<StPhotoInput
type="file"
name="img"
accept="image/jpeg"
onChange={fileInputHandler}
required
/>
이렇게 파일을 input 하게 됐을 때, 이를 관리해주는 onChange 함수는 다음과 같다.
useInput.jsx 중 일부
// 이미지 파일 업로드 함수
const fileInputHandler = async (e) => {
const { name } = e.target;
const imgData = e.target.files[0];
const compressImgHandler = (fileSrc) => {
const options = {
maxSizeMB: 5,
maxWidthOrHeight: 640,
useWebWorker: true,
};
try {
const compressedFile = imageCompression(fileSrc, options);
return compressedFile;
} catch (error) {
alert("이미지 파일이 너무 큽니다!");
}
};
const compressedImg = await compressImgHandler(imgData);
setInputValue({ ...inputValue, [name]: compressedImg });
};
이거저거 구글링 해보다가, 이미지를 압축해주는 라이브러리를 찾아서 해봤는데, 뭔가 설정을 잘못한 건지 이미지 크기가 유의미하게 크게 줄어들지는 않는다. 좀 더 찾아볼 것.
그리고 저렇게 파일을 압축하게 됐을 때 콘솔을 찍어보면 blob형식으로 파일이 저장된 것을 볼 수 있다.
이미지 압축 라이브러리 https://www.npmjs.com/package/browser-image-compression
이후, formData를 생성하여 그 안에 파일을 넣어주면 된다.
const formData = new FormData();
formData.append("image", inputValue.img, "image");
// append(key, value, title)
// key 값은 서버와 꼭 맞춰주는 것이 좋다. api 명세서 참고!
// value 안에는 첨부한 파일을 넣어준다.
// 파일 이름을 따로 설정하지 않으면 그냥 blob으로 간다.
이후 axios.post에 request body 값으로 서버에 전송해주면 된다.