음식 인식을 위한 음식 사진, 유저 사진 등 서버로 이미지를 전송해야할 필요가 있었다.
기존에는 base64 방식을 채택했으나, 서버로 전송하는데 시간이 오래 걸려 이 부분을 개선하기로 했다.
이미지 전송에는 여러 가지 방법이 있지만,
대표적인 방식인 Base64와 FormData에 대해 알아보도록 하자!
📍Base64 인코딩
이진 데이터를 64개의 ASCII 문자로 변환하는 방식이다.
인코딩 방법
24비트 버퍼에 위쪽(MSB)부터 한 바이트씩 세 바이트를 집어넣는다. (버퍼의 남은 부분은 0으로 채워넣는다.)
그리고, 버퍼의 위쪽부터 6비트(2^6=64)씩 잘라 그 값을 읽어 Base64 색인표와 맵핑한다.
이 과정을 거치면 4개의 ASCII 문자로 변환된다.
++예시
특징
- 데이터 손실 방지: 이진 데이터를 ASCII 문자열로 변환하므로, 데이터 전송 중에 발생할 수 있는 데이터 손실을 방지할 수 있다.
- 호환성: ASCII 문자만을 사용하므로, 대부분의 시스템과 호환된다.
- URL 안전: Base64 인코딩된 문자열은 URL에 안전하게 포함될 수 있다.
그러나, 원래 3바이트(24비트)의 이진 데이터가 4개의 ASCII 문자로 변환되므로, 데이터 크기가 약 33% 증가하게 된다.
따라서 대용량의 데이터를 전송하는 경우에는 비효율적일 수 있다.
📍Form Data
JavaScript에서 XMLHttpRequest, Fetch와 같은 웹 API와 호환되는 방식으로 데이터를 보내기 위한 객체이다.
이때 Form은 웹 폼(Form)을 의미하는데, 사용자가 입력한 데이터를 서버로 전송하는 데 사용되는 HTML 요소이다.
FormData 객체는 이 웹 폼의 데이터를 표현하는 데 사용되며, 각 키-값 쌍은 폼의 각 필드를 나타낸다.
HTTP 요청으로 서버 전송할 때, Content-Type 헤더 속성은 multipart/form-data라는 MIME타입이고, 인코딩되어 전송된다.
- MIME 타입
: Multipurpose Internet Mail Extensions
: 이메일 보낼 때 사용되는 인터넷 표준이다. 원래는 이메일에서 비-ASCII 문자를 지원하기 위해 만들어졌지만, 현재는 웹에서도 널리 사용되고 있다.
: 타입(type)과 서브타입(subtype)이라는 두 부분으로 이루어져 있다. 이 두 부분은 슬래시(/)로 구분된다.
: 웹에서는 HTTP 응답의 'Content-Type' 헤더에 MIME 타입을 지정하여, 클라이언트에게 응답의 내용이 어떤 형식인지 알려준다. 이를 통해 클라이언트는 적절한 방식으로 데이터를 처리할 수 있다.
사용 방법
FormData 객체 생성 후, append(key, value)를 통해 데이터를 추가할 수 있다.
이때, iOS에서 파일의 URI가 'file://'로 시작하는데, 이 부분을 제거하지 않으면 일부 라이브러리나 API에서 파일을 제대로 인식하지 못할 수 있다. 따라서 iOS에서 파일을 FormData로 전송할 때는 'file://' 부분을 제거해야 한다.
const form = new FormData();
const uri =
Platform.OS === 'android'
? uploadInfo.file
: uploadInfo.file.replace('file://', '');
form.append('name', testName);
form.append('image', {
uri,
name: 'image.jpg',
type: 'image/jpg',
})
서버에 전송하는 방법은 다음과 같다.
// fetch 이용
async function uploadData() {
try {
const response = await fetch('서버 URL', {
method: 'POST',
body: form,
headers: {
'Content-Type': 'multipart/form-data',
},
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
uploadData();
// axios 이용
async function uploadData() {
try {
const response = await axios.post('서버 URL', form, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
console.log(response);
} catch (error) {
console.error(error);
}
}
uploadData();
참고
https://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464
https://developer.mozilla.org/en-US/docs/Web/API/FormData
'Language > JavaScript' 카테고리의 다른 글
[JS] 타입과 객체 (0) | 2024.02.28 |
---|---|
[JS] 변수 선언 (0) | 2024.02.26 |
[JS] JavaScript 역사 (0) | 2024.02.26 |
JavaScript 기초와 활용(feat. 조코딩) (0) | 2023.02.18 |