How to Encode Base64 in JavaScript
Base64 encoding is essential for embedding images, transmitting binary data, and working with APIs. JavaScript provides built-in methods for Base64 operations. This tutorial covers encoding, decoding, and handling special cases like Unicode text and files.
Method 1: Built-in btoa() and atob()
The simplest way to encode Base64 in browsers:
// Encode to Base64
const text = 'Hello, World!';
const encoded = btoa(text);
console.log(encoded);
// "SGVsbG8sIFdvcmxkIQ=="// Decode from Base64
const decoded = atob(encoded);
console.log(decoded);
// "Hello, World!"
What Do btoa and atob Mean?
- btoa: "Binary to ASCII" (encode)
- atob: "ASCII to Binary" (decode)
Browser Support
| Browser | Support | |---------|---------| | Chrome | ✅ All versions | | Firefox | ✅ All versions | | Safari | ✅ All versions | | Edge | ✅ All versions | | Node.js | ❌ Not available |
Method 2: Buffer API (Node.js)
For server-side JavaScript:
// Encode
const text = 'Hello, World!';
const encoded = Buffer.from(text, 'utf-8').toString('base64');
console.log(encoded);
// "SGVsbG8sIFdvcmxkIQ=="// Decode
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded);
// "Hello, World!"
Universal Function (Browser + Node.js)
function encodeBase64(str) {
if (typeof Buffer !== 'undefined') {
// Node.js
return Buffer.from(str, 'utf-8').toString('base64');
} else {
// Browser
return btoa(unescape(encodeURIComponent(str)));
}
}function decodeBase64(str) {
if (typeof Buffer !== 'undefined') {
// Node.js
return Buffer.from(str, 'base64').toString('utf-8');
} else {
// Browser
return decodeURIComponent(escape(atob(str)));
}
}
Handling Unicode Characters
The built-in btoa() only works with ASCII characters. For Unicode:
// ❌ This fails with non-ASCII characters
btoa('你好'); // Error// ✅ Use this for Unicode
const text = '你好,世界!';
const encoded = btoa(unescape(encodeURIComponent(text)));
console.log(encoded);
// "5L2g5aW977yB5LiW55WMISIK
// Decode
const decoded = decodeURIComponent(escape(atob(encoded)));
console.log(decoded);
// "你好,世界!"
Why This Works
1. encodeURIComponent() converts Unicode to UTF-8 percent-encoded
2. unescape() converts percent-encoded to binary string
3. btoa() encodes binary string to Base64
Encoding Files and Images
File to Base64
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}// Usage
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
const file = e.target.files[0];
const base64 = await fileToBase64(file);
console.log(base64);
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
});
Image URL to Base64
async function imageUrlToBase64(url) {
const response = await fetch(url);
const blob = await response.blob(); return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
// Usage
const base64 = await imageUrlToBase64('https://example.com/image.png');
console.log(base64);
Base64 to Blob (for Download)
function base64ToBlob(base64, mimeType) {
const byteCharacters = atob(base64.split(',')[1] || base64);
const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: mimeType });
}
// Usage
const blob = base64ToBlob('data:image/png;base64,iVBORw0KGgoAAA...', 'image/png');
// Download
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'image.png';
a.click();
URL.revokeObjectURL(url);
URL-Safe Base64 Encoding
Standard Base64 uses + and / which aren't URL-safe:
function base64UrlEncode(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}function base64UrlDecode(str) {
// Add padding if needed
const padding = '='.repeat((4 - str.length % 4) % 4);
const base64 = str.replace(/-/g, '+').replace(/_/g, '/') + padding;
return atob(base64);
}
// Usage
const urlSafe = base64UrlEncode('Hello+World/Test');
console.log(urlSafe);
// "SGVsbG8rV29ybGQvVGVzdA" (no + or /)
Complete Base64 Utility Class
class Base64Utils {
// Encode text to Base64
static encode(text) {
if (typeof Buffer !== 'undefined') {
return Buffer.from(text, 'utf-8').toString('base64');
}
return btoa(unescape(encodeURIComponent(text)));
} // Decode Base64 to text
static decode(base64) {
if (typeof Buffer !== 'undefined') {
return Buffer.from(base64, 'base64').toString('utf-8');
}
return decodeURIComponent(escape(atob(base64)));
}
// URL-safe encoding
static encodeUrlSafe(text) {
return this.encode(text)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// URL-safe decoding
static decodeUrlSafe(base64) {
const padding = '='.repeat((4 - base64.length % 4) % 4);
const standard = base64
.replace(/-/g, '+')
.replace(/_/g, '/') + padding;
return this.decode(standard);
}
// File to Base64
static fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
// Base64 to Blob
static base64ToBlob(base64, mimeType) {
const data = base64.includes(',') ? base64.split(',')[1] : base64;
const byteCharacters = atob(data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
return new Blob([new Uint8Array(byteNumbers)], { type: mimeType });
}
}
// Usage
const encoded = Base64Utils.encode('Hello, 世界!');
const decoded = Base64Utils.decode(encoded);
const urlSafe = Base64Utils.encodeUrlSafe('Hello+World');
Common Use Cases
Embedding Images in HTML
// Create data URL for inline image
const img = document.createElement('img');
img.src = await Base64Utils.fileToBase64(fileInput.files[0]);
document.body.appendChild(img);Storing Binary Data in JSON
const payload = {
filename: 'document.pdf',
mimeType: 'application/pdf',
data: Base64Utils.encode(fileContent)
};// Send via API
fetch('/api/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
Basic Authentication Header
const credentials = 'username:password';
const encoded = Base64Utils.encode(credentials);
const headers = {
'Authorization': Basic ${encoded}
};Try It Online
Need to encode Base64 quickly? Use our Base64 Encoder for instant encoding with file support and URL-safe options.
Conclusion
For simple ASCII encoding in browsers, btoa() works well. For Unicode support and Node.js, use the Buffer approach or the utility class above. Always handle Unicode properly to avoid encoding errors.
For related topics, see How to Decode a JWT Token which uses Base64url encoding.
---
Related Tools: