- 문제내용
- singup POST 요청에서 data와 imageFile을 같이 넘겨주지 못하는 문제가 발생
- message : “Failed to parse multipart servlet request”
- 해결방법
- 시도한 방법
- 업로드한 파일을 프리뷰하기 위해 만들어 놓은 코드에서 실제 API에 이미지를 보내려면 객체로 보내야 한다. setImageFile(e.target.files[0]); 프리뷰 처리와 API에 이미지를 보낼 때 데이터 타입이 달라서 에러가 발생했다. 이를 수정했다.
- axios.js 에서 이미지 파일을 업로드하는 API에 대한 header 타입을 지정해줬다.
// 프로필 사진 입력
const imgRef = useRef();
const [profileImage, setProfileImage] = useState(null);
const onChangeImage = (e) => {
if (e.target.files.length > 0) {
setProfileImage(e.target.files[0]);
let reader = new FileReader();
let file = imgRef.current.files[0];
reader.onloadend = () => {
setImageFile(reader.result);
}
reader.readAsDataURL(file);
}
};
axios.interceptors.request.use(
(config) => {
const accessToken = Cookies.get("ACCESS_TOKEN");
if (accessToken) {
if (!config.url.includes(`https://dapi.kakao.com/`)){
config.headers["ACCESS_TOKEN"] = "Bearer " + accessToken.trim();
}
}
if (config.url === '/signup'){
config.headers["Content-Type"] = "application/json";
}
else if(config.url.includes(`/uploadImg`)){
config.headers["Content-Type"] = "multipart/form";
//중략
return config;
},
(error) => {
Promise.reject(error);
}
);
- 해결한 방법
- upload API를 사용하여 imageUrl을 받은 뒤에 singup API에 imageUrl을 넣어 POST 요청을 보내는 방식으로 사용
const submitHandler = async (e) => {
e.preventDefault();
try {
const formData = new FormData();
formData.append('name', name);
formData.append('email', email);
formData.append('password', pw);
formData.append('nickname', nickname);
formData.append('gender', gender);
formData.append('birth', birth);
formData.append('phoneNum', phoneNum);
// ImageFormData
const ImageFormData = new FormData();
ImageFormData.append('imageFile', profileImage);
// 이미지를 먼저 업로드 한 뒤, 3S 저장 URL을 response 받는다.
const IMAGE_UPLOAD_URL = `${process.env.REACT_APP_SERVER_URL}/uploadImg`;
const uploadRes = await axios.post(IMAGE_UPLOAD_URL, ImageFormData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
// 상기 uploadRes api의 response 가 완료된 이후 formData append 처리.
// 만약 uploadRes.data 를 불러올 수 없는 경우에 대한 리스크 처리 필요.
formData.append('imageUrl', uploadRes.data);
const originUrl = `${process.env.REACT_APP_SERVER_URL}/signup`;
// eslint-disable-next-line
const signupResponse = await axios.post(originUrl, formData, {
headers: {
'Content-Type': 'application/json'
}
});
swal('회원가입 성공!');
goLogin();
} catch (error) {
console.error(error);
}
};