JavaScript에서 Base64 인코딩/디코딩: btoa(), atob() 및 유니코드
JavaScript에서 Base64 인코딩 및 디코딩
JavaScript는 Base64 문자열을 인코딩하고 디코딩하는 여러 가지 내장 방법을 제공합니다. 브라우저 애플리케이션을 구축하든 Node.js 서버를 구축하든, JSON, HTML, URL과 같은 텍스트 기반 형식에서 이진 데이터를 처리하려면 Base64 작업 방법을 이해하는 것이 필수적입니다.
브라우저에서 btoa() 및 atob() 사용하기
브라우저 JavaScript에서 Base64를 위한 두 가지 핵심 함수는 btoa()와 atob()입니다. 이 함수 이름은 오래된 명명 규칙을 따릅니다. btoa는 "binary to ASCII"를, atob은 "ASCII to binary"를 의미합니다. 이 함수들은 수십 년 동안 모든 주요 브라우저에서 지원되어 왔습니다.
btoa()로 인코딩하기
const originalString = 'Hello, world!';
const encoded = btoa(originalString);
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
atob()로 디코딩하기
const base64String = 'SGVsbG8sIHdvcmxkIQ==';
const decoded = atob(base64String);
console.log(decoded);
// Output: Hello, world!
두 함수 모두 Latin-1 문자(각 문자가 단일 바이트로 표현됨)만 포함된 문자열에서 작동합니다. 이는 다음에 다룰 중요한 제한 사항입니다.
유니코드 및 비ASCII 문자 처리하기
흔한 함정: btoa()는 이모지, 한자, 악센트 문자 등 Latin-1 범위를 벗어난 문자가 포함된 문자열을 받으면 오류를 발생시킵니다.
btoa('Hello 你好');
// Error: The string to be encoded contains characters outside of the Latin-1 range.
유니코드 문자열을 인코딩하려면 먼저 문자열을 바이트로 변환한 다음 해당 바이트를 인코딩해야 합니다. 현대적인 접근 방식은 TextEncoder 및 TextDecoder API를 사용합니다:
function unicodeToBase64(str) {
const bytes = new TextEncoder().encode(str);
const binaryString = String.fromCharCode(...bytes);
return btoa(binaryString);
}
function base64ToUnicode(base64) {
const binaryString = atob(base64);
const bytes = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
// Usage
const encoded = unicodeToBase64('Hello 你好 🚀');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = base64ToUnicode(encoded);
console.log(decoded);
// Output: Hello 你好 🚀
구식 기법으로 encodeURIComponent와 decodeURIComponent를 사용할 수도 있지만, TextEncoder/TextDecoder 접근 방식이 더 견고하며 권장되는 현대적인 솔루션입니다.
이진 데이터(ArrayBuffer) 인코딩하기
파일, 이미지, 또는 fetch나 FileReader와 같은 API에서 가져온 원시 이진 데이터를 다룰 때는 일반적으로 ArrayBuffer 또는 Uint8Array를 사용합니다. 이를 Base64로 변환하는 방법은 다음과 같습니다:
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binaryString = '';
for (let i = 0; i < bytes.length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
return btoa(binaryString);
}
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
브라우저에서 파일을 Base64로 변환하기
다음은 FileReader를 사용하여 사용자가 선택한 파일을 Base64 데이터 URL로 변환하는 완전한 예제입니다:
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(new Error('Failed to read file'));
reader.readAsDataURL(file);
});
}
// Usage with a file input
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const dataUrl = await fileToBase64(file);
console.log(dataUrl); // data:image/png;base64,iVBORw0KGgo...
} catch (err) {
console.error('Conversion failed:', err);
}
});
Node.js에서 Base64 사용하기
Node.js는 Base64 작업을 위한 Buffer 클래스를 제공하며, 이는 브라우저의 btoa/atob보다 더 유연합니다. Buffer 클래스는 유니코드를 포함한 인코딩 및 디코딩을 자동으로 처리하며, 여러 인코딩 형식을 지원합니다.
기본 인코딩 및 디코딩
// Encode a string to Base64
const encoded = Buffer.from('Hello, world!').toString('base64');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ==
// Decode a Base64 string back to text
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Node.js에서 유니코드 지원
브라우저의 btoa()와 달리, Node.js Buffer는 유니코드를 원활하게 처리합니다:
const encoded = Buffer.from('Hello 你好 🚀').toString('base64');
console.log(encoded);
// Output: SGVsbG8g5L2g5aW9IPCfj4A=
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// Output: Hello 你好 🚀
파일을 읽어 Base64로 인코딩하기
const fs = require('fs');
// Read a file and encode it to Base64
const buffer = fs.readFileSync('image.png');
const base64 = buffer.toString('base64');
const dataUrl = `data:image/png;base64,${base64}`;
Node.js에서 Base64url 인코딩
Node.js 15.7.0 이상에서는 네이티브 Base64url 인코딩을 지원하며, 이는 +를 -로, /를 _로 대체하고 패딩을 생략합니다:
const encoded = Buffer.from('Hello, world!').toString('base64url');
console.log(encoded);
// Output: SGVsbG8sIHdvcmxkIQ (no padding)
const decoded = Buffer.from(encoded, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
성능 고려 사항
대용량 데이터의 경우 반복적인 Base64 작업이 느려질 수 있습니다. 다음은 몇 가지 팁입니다:
- 유니코드 문자열에는 수동 변환보다
TextEncoder/TextDecoder를 사용하세요 - Node.js에서는
Buffer.from()이 고도로 최적화되어 있으므로 수동 구현보다 선호하세요 - 필요한 경우가 아니라면 대용량 파일을 Base64로 변환하지 마세요(스트리밍 고려)
- 대용량 데이터셋의 경우 브라우저에서
Blob과FileReader를 사용하여 메인 스레드 차단을 방지하세요
온라인으로 Base64 인코딩 체험하기
코딩 없이 브라우저에서 바로 인코딩과 디코딩을 실험해 보세요. 무료 온라인 Base64 인코더 및 디코더를 사용하세요. 텍스트를 붙여넣거나 파일을 업로드하기만 하면 즉시 Base64 결과를 얻을 수 있습니다.