react native 에서 이미지는
react native 의 FormData() 모듈을 사용하면 쉽게 받을 수 있다
ajax 로 json 구조의 데이터를 전송할 수 있는 객체로
이미지를 base64, buffer, 이진 형식으로 전송할 수 있다
ajax 는 기본적으로 페이지 전환 없이 폼 데이터를 제출한다
FormData() 객체를 new 연산자를 통해 생성하고
append() 메소드를 통해 key(string) : value 형식으로 데이터를 추가할 수 있다
이미지
의 경우 append 시 uri, type, name(확장자 포함 파일명) 세가지 속성과 각 속성별 값이 포함되어 있어야 한다
type
이 작성되어있지 않으면 Network Error 가 발생한다고 하니 주의해야 함이미지의 name
과 formData 의 name
은 별개이니 또 주의해야 함..// react-native-image-picker 의 launchImageLibrary 사용
// launchImageLibrary 는 기기 사진첩 내의 사진 주소를 반환한다
if (type === 'gallery') {
handlePermission(
'ios.permission.PHOTO_LIBRARY',
'android.permission.READ_MEDIA_IMAGES',
);
func = launchImageLibrary;
}
const result = await func(imagePickerOption);
if (result.assets) {
const source = result.assets[0];
setPickedImage(source.uri);
}
uri: Platform.OS === 'ios'
? pickedImage.replace('file://', '')
: pickedImage,
보내야 할 모든 이미지를 추가했다면 api 통신을 통해 이미지를 서버로 전송할 수 있다..
이미지 파일은 string이 아니라 Blob 형식 데이터이기 때문에
파일 변환을 해야하는데 FormData 를 활용하여 변환해주는
axios v0.25 이상일 경우
react native 에서 axios post 시
body의 데이터들을 모두 string 형식으로 변환하는 버그가 있다
때문에 formData 를 string 으로 인식하여
요청 에러 (400 error) 가 발생한다
headers 에서 content-type 을 multipart/form-data 로 설정 해주고
transformRequest 를 사용하여 data 형식을 그대로 반환하도록 작성한다
transformRequest 는 데이터 형식을 요청 전에 변환하여 전송할 수 있도록 하는
함수를 작성하는데 react-native 에서만 default 가 string 인 것 같다
아래와 같이 data 를 그대로 반환하도록 하면 formData 형식을 그대로 전송할 수 있게 된다
const image = {
name: 'image1', // 한글을 사용하면 안된다.... ios 는 되는데 android 는 안됨 encoding 이 다르다
type: image/jpg,
uri: Platform.OS === 'ios'
? pickedImage.replace('file://', '')
: pickedImage,
}
const formData = new FormData()
formData.append('name', image)
api({
method: 'POST',
url: 'url',
data: formData,
headers: {
Accept: '*/*',
'Content-type': 'multipart/form-data',
},
transformRequest: data => data,
});
https://lwamuhaji.tistory.com/61?category=535757
배열 전송 시 같은 name 에 여러번 데이터를 넣어서 전송할 수 있다
const formData = new FormData()
images.forEach(item => {
formData.append('files', {
name: 'picture1', // 한글 x
type: 'image/jpg',
uri: Platform.OS === 'ios' ? item?.replace('file://', '') : item,
});
});