react native axios form error

지리·2022년 9월 18일
0

문제상황1

react-native-image-crop-picker를 이용해 이미지를 서버로 보내는 과정에서 500이 나왔다. 웹에서 똑같은 값으로 axios통신을 했을땐 잘됐는데 앱에서만 에러가 뜸...

const getImg = () => {
	ImagePicker.openPicker({
		width: 300,
		height: 300,
		cropping: true,
		cropperCircleOverlay: true,
		forceJpg: true,
	}).then(image => {
		editUserImg.mutate(image);
	});
};

const editUserImg = useMutation(image => patchUserImage(image), {
	onSuccess: () => {
		queryClient.invalidateQueries('userData', {exact: true});
	},
	onError: e => {
		console.log(e.toJSON());
	},
});

export async function patchUserImage(image) {
	const formData = new FormData();
	let pathParts = image.path.split('/');
	
	const form = {
		name: pathParts[pathParts.length - 1],
		type: 'image/jpeg',
		uri: image.path,
		size: image.size,
	};  

	formData.append('file', form);

	const response = await axios({
		method: 'PATCH',
		url: 'user/profile',
		headers: {
		'Content-Type': 'multipart/form-data',
	},
		data: formData,
	});

	return response.data;

}

React Native POST "multpart form-data" 500 server error
왜인지 모르겠지만 form데이터를 넣을때 header도 같이 넣어서 했더니 제대로 동작함...

수정코드

const getImg = () => {
	ImagePicker.openPicker({
		width: 300,
		height: 300,
		cropping: true,
		cropperCircleOverlay: true,
		forceJpg: true,
	}).then(image => {
		editUserImg.mutate(image);
	});
};

const editUserImg = useMutation(image => patchUserImage(image), {
	onSuccess: () => {
		queryClient.invalidateQueries('userData', {exact: true});
	},
	onError: e => {
		console.log(e.toJSON());
	},
});

export async function patchUserImage(image) {
	const formData = new FormData();
	let pathParts = image.path.split('/');
	
	const form = {
		name: pathParts[pathParts.length - 1],
		type: 'image/jpeg',
		uri: image.path,
		size: image.size,
		
		//헤더부분을 추가함
		headers: {
		'Content-Type': 'multipart/form-data',
		
	};  

	formData.append('file', form);

	const response = await axios({
		method: 'PATCH',
		url: 'user/profile',
	},
		data: formData,
	});

	return response.data;

}

문제상황2

이번에는 서버와의 통신은 성공했는데 aws 서버에는 이미지가 안올라가졌다...이것도 웹으로는 문제없었는데 앱에서만 이럼

codingbutterfly -> 누가 감사하게도 react native에서 이미지 업로드를 프론트에서 서버과정까지 구현과정을 적은걸 찾았고 이분도 비슷한 문제가 있었는데 axios말고 fetch를 이용해야 한다고함...

const getImg = () => {
	ImagePicker.openPicker({
		width: 300,
		height: 300,
		cropping: true,
		cropperCircleOverlay: true,
		forceJpg: true,
	}).then(image => {
		editUserImg.mutate(image);
	});
};

const editUserImg = useMutation(image => patchUserImage(image), {
	onSuccess: () => {
		queryClient.invalidateQueries('userData', {exact: true});
	},
	onError: e => {
		console.log(e.toJSON());
	},
});

export async function patchUserImage(image) {
	const formData = new FormData();
	let pathParts = image.path.split('/');
	
	const form = {
		name: pathParts[pathParts.length - 1],
		type: 'image/jpeg',
		uri: image.path,
		size: image.size,
	};  

	formData.append('file', form);
	
	//axios구문을 fetch로 수정했다
	const response = await fetch('http://54.180.178.53:3000/user/profile', {
		method: 'PATCH',
		body: formData,
		headers: {
			Accept: 'application/json',
			'Content-Type': 'multipart/form-data',
			},
		});

	return response.data;

}

fetch로 수정하니 이미지 업로드가 잘됨,...

해결

Can't post FormData since Axios 0.25.0
axios자체의 문제였던것 같음
에러가 나던 버전은 v0.26.1
formData가 읽혀지려면 transformRequest가 들어가야 formData가 서버에서 제대로 읽히는듯

axios.post(url, formData, {
  headers: { 'Content-Type': 'multipart/form-data' },
  transformRequest: formData => formData, //<-이부분이 추가 되어야함
})

v0.24.0버전은 에러없는 버전인듯 하다 이버전을 쓰면 transform...부분 안넣어도 됨
에러수정된 버전은 v0.27.0인것 같음^^ -> 이버전으로 바꿨고 transform...부분 이 없어도됨

최종코드

const getImg = () => {
	ImagePicker.openPicker({
		width: 300,
		height: 300,
		cropping: true,
		cropperCircleOverlay: true,
		forceJpg: true,
	}).then(image => {
		editUserImg.mutate(image);
	});
};

const editUserImg = useMutation(image => patchUserImage(image), {
	onSuccess: () => {
		queryClient.invalidateQueries('userData', {exact: true});
	},
	onError: e => {
		console.log(e.toJSON());
	},
});


export async function patchUserImage(image) {
	const formData = new FormData();
	let pathParts = image.path.split('/');
	
	const form = {
		name: pathParts[pathParts.length - 1],
		type: 'image/jpeg',
		uri: image.path,
		size: image.size,
	};
	
	formData.append('file', form);
	
	const response = await client.patch('user/profile', formData, {
		headers: {
			'Content-Type': 'multipart/form-data',
		},
	});  
	
	return response.data;

}
profile
공부한것들, 경험한 것들을 기록하려 노력합니다✨

0개의 댓글