TIL: RN | image 업로드 (formData) - 221106

Lumpen·2022년 11월 7일
0

TIL

목록 보기
184/244
post-custom-banner

react native 에서 이미지는
react native 의 FormData() 모듈을 사용하면 쉽게 받을 수 있다

ajax 로 json 구조의 데이터를 전송할 수 있는 객체로
이미지를 base64, buffer, 이진 형식으로 전송할 수 있다

ajax 는 기본적으로 페이지 전환 없이 폼 데이터를 제출한다

FormData

FormData() 객체를 new 연산자를 통해 생성하고
append() 메소드를 통해 key(string) : value 형식으로 데이터를 추가할 수 있다
이미지의 경우 append 시 uri, type, name(확장자 포함 파일명) 세가지 속성과 각 속성별 값이 포함되어 있어야 한다

  • 특히 type 이 작성되어있지 않으면 Network Error 가 발생한다고 하니 주의해야 함
  • 이 때 이미지의 nameformData 의 name 은 별개이니 또 주의해야 함..
  • iOS 의 경우 image uri 에 'file://' 문자열을 포함하면 안되기 때문에 아래와 같이 replace 처리 해준다
// 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://www.inflearn.com/questions/504857/axios-0-25-%EC%9D%B4%EC%83%81%EC%97%90%EC%84%9C-multipart-form-data-%EB%AC%B8%EC%A0%9C

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,
        });
      });
profile
떠돌이 생활을 하는. 실업자, 부랑 생활을 하는
post-custom-banner

0개의 댓글