首页 / 博客 / JavaScript Base64 解码
JavaScript Base64 解码完全指南 2026
最后更新:2026年5月16日 · 阅读约10分钟
Base64 编码无处不在 — 从在 HTML 中嵌入图片到 API 中传输二进制数据。做 JavaScript 开发,掌握 Base64 编解码是基本功。这篇指南从基础的 atob/btoa 函数讲起,覆盖 Unicode 文本处理、二进制数据,以及浏览器和 Node.js 的区别。
快速提示:现在就想解码 Base64?试试我们的免费 在线 Base64 编解码工具 — 粘贴文本立即解码,无需注册。
基础:atob 和 btoa
JavaScript 在浏览器端提供了两个内置函数:
btoa()— Binary to ASCII(把字符串编码成 Base64)atob()— ASCII to Binary(把 Base64 字符串解码回来)
// 编码
const encoded = btoa("Hello World");
console.log(encoded); // "SGVsbG8gV29ybGQ="
// 解码
const decoded = atob("SGVsbG8gV29ybGQ=");
console.log(decoded); // "Hello World"
看起来很简单。但有个坑 — btoa() 和 atob() 只能正确处理 Latin1(ASCII)字符。试试编码中文或 emoji,直接报错。
Unicode 问题
用 btoa 处理非 ASCII 文本会怎样:
// 直接报错!
try {
btoa("你好世界");
} catch (e) {
console.error(e.message);
// "Failed to execute 'btoa': The string to be encoded contains characters outside of the Latin1 range."
}
btoa/atob 只能处理 0x00–0xFF 范围的字符。要完整支持 Unicode,需要换一种方式。
Unicode 的 Base64:TextEncoder 和 TextDecoder
现代方案是用 TextEncoder 和 TextDecoder 在字符串和字节数组之间转换,再配合 Base64 转换:
// Unicode 字符串编码为 Base64
function encodeBase64(str) {
const encoder = new TextEncoder();
const bytes = encoder.encode(str);
let binary = '';
bytes.forEach(byte => binary += String.fromCharCode(byte));
return btoa(binary);
}
// Base64 解码为 Unicode 字符串
function decodeBase64(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
// 现在支持 Unicode 了!
const encoded = encodeBase64("你好世界 🌍");
console.log(encoded); // "5L2g5aW95LiW55WJIPCfjI0="
const decoded = decodeBase64("5L2g5aW95LiW55WJIPCfjI0=");
console.log(decoded); // "你好世界 🌍"
更简洁的写法
也可以用展开运算符写得更简洁:
// 简洁编码
function toBase64(str) {
return btoa(String.fromCharCode(...new TextEncoder().encode(str)));
}
// 简洁解码
function fromBase64(b64) {
return new TextDecoder().decode(
Uint8Array.from(atob(b64), c => c.charCodeAt(0))
);
}
console.log(toBase64("Hello 你好")); // "SGVsbG8g5L2g5aW9"
console.log(fromBase64("SGVsbG8g5L2g5aW9")); // "Hello 你好"
注意:展开运算符的方式(...new TextEncoder().encode(str))在处理超大字符串(10万+字符)时可能触发最大调用栈限制。大数据量用循环方式更稳。
处理二进制数据
文件编码为 Base64
在浏览器中处理文件时,经常需要把 File 或 Blob 转成 Base64:
// 用 FileReader(回调方式)
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
// result 是 data URL,如 "data:image/png;base64,iVBOR..."
const base64 = reader.result.split(',')[1];
resolve(base64);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
// 使用
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
const base64 = await fileToBase64(file);
console.log(base64);
});
用 arrayBuffer 的现代方式
// 用 arrayBuffer(现代、基于 Promise)
async function fileToBase64Modern(file) {
const buffer = await file.arrayBuffer();
const bytes = new Uint8Array(buffer);
let binary = '';
bytes.forEach(byte => binary += String.fromCharCode(byte));
return btoa(binary);
}
Base64 转回 Blob
function base64ToBlob(base64, mimeType = 'application/octet-stream') {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return new Blob([bytes], { type: mimeType });
}
// 创建下载链接
const blob = base64ToBlob("SGVsbG8gV29ybGQ=", "text/plain");
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt';
a.click();
URL.revokeObjectURL(url);
Node.js 中的 Base64
Node.js 没有全局的 atob/btoa(Node 16+ 才加了)。标准做法是用 Buffer:
用 Buffer 编码
// 字符串编码为 Base64
const str = "Hello World 你好";
const encoded = Buffer.from(str, 'utf-8').toString('base64');
console.log(encoded); // "SGVsbG8gV29ybGQg5L2g5aW9"
// Base64 解码为字符串
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded); // "Hello World 你好"
Node.js 中处理文件
const fs = require('fs');
// 读取文件编码为 Base64
const fileBuffer = fs.readFileSync('image.png');
const base64 = fileBuffer.toString('base64');
console.log(base64);
// Base64 解码写入文件
const decoded = Buffer.from(base64, 'base64');
fs.writeFileSync('output.png', decoded);
Node.js 16+ 的 atob/btoa
// Node 16+ 有全局 atob/btoa
const encoded = btoa("Hello World");
console.log(encoded); // "SGVsbG8gV29ybGQ="
const decoded = atob("SGVsbG8gV29ybGQ=");
console.log(decoded); // "Hello World"
注意:Node.js 的 atob/btoa 和浏览器版一样有 Latin1 限制。处理 Unicode 还是用 Buffer 靠谱。
浏览器 vs Node.js:关键区别
- 浏览器:ASCII 用
atob()/btoa(),Unicode 用TextEncoder/TextDecoder - Node.js:直接用
Buffer,原生支持 Unicode - 同构代码:用
TextEncoder/TextDecoder— 两个环境都支持
// 通用写法(浏览器和 Node.js 18+ 都能用)
function universalEncode(str) {
const bytes = new TextEncoder().encode(str);
let binary = '';
bytes.forEach(byte => binary += String.fromCharCode(byte));
return btoa(binary);
}
function universalDecode(b64) {
const binary = atob(b64);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
URL 安全的 Base64
标准 Base64 中的 + 和 / 在 URL 里有特殊含义。URL 安全的 Base64 会替换它们:
// 标准 Base64 转 URL 安全
function base64ToUrlSafe(base64) {
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
// URL 安全转回标准 Base64
function urlSafeToBase64(urlSafe) {
let base64 = urlSafe.replace(/-/g, '+').replace(/_/g, '/');
// 补齐填充
while (base64.length % 4) base64 += '=';
return base64;
}
const encoded = btoa("Hello+World/Test");
const urlSafe = base64ToUrlSafe(encoded);
console.log(urlSafe); // "SGVsbG8rV29ybGQvVGVzdA"
const restored = urlSafeToBase64(urlSafe);
console.log(atob(restored)); // "Hello+World/Test"
常见使用场景
图片的 Data URL
// 从 Base64 创建 data URL
const base64Image = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
const dataUrl = `data:image/png;base64,${base64Image}`;
// 用在 img 标签中
const img = document.createElement('img');
img.src = dataUrl;
document.body.appendChild(img);
HTTP Basic 认证
// 创建 Basic Auth 请求头
const username = "admin";
const password = "secret";
const credentials = btoa(`${username}:${password}`);
fetch('/api/data', {
headers: {
'Authorization': `Basic ${credentials}`
}
});
localStorage 存储数据
// 把复杂数据存为 Base64
const data = { theme: "dark", lang: "zh-CN" };
const json = JSON.stringify(data);
const encoded = btoa(unescape(encodeURIComponent(json)));
localStorage.setItem('settings', encoded);
// 读取
const stored = localStorage.getItem('settings');
const decoded = decodeURIComponent(escape(atob(stored)));
const settings = JSON.parse(decoded);
错误处理
// 安全的 Base64 解码
function safeDecodeBase64(base64) {
try {
// 验证 Base64 格式
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) {
throw new Error('无效的 Base64 格式');
}
return atob(base64);
} catch (e) {
console.error('Base64 解码失败:', e.message);
return null;
}
}
// 测试
console.log(safeDecodeBase64("SGVsbG8=")); // "Hello"
console.log(safeDecodeBase64("not-valid!")); // null
常见问题
atob 和 btoa 有什么区别?
btoa() 把字符串编码成 Base64(binary to ASCII)。atob() 把 Base64 字符串解码回来(ASCII to binary)。它们是互逆操作。
为什么 btoa 处理中文会报错?
btoa() 只支持 Latin1 字符(0x00–0xFF)。处理 Unicode 文本需要先用 TextEncoder 转成字节再编码。参考上面的 Unicode 部分。
如何在 JavaScript 中把文件编码为 Base64?
浏览器端用 FileReader.readAsDataURL() 或 file.arrayBuffer() 配合 btoa()。Node.js 用 fs.readFileSync('file').toString('base64')。
浏览器和 Node.js 的 Base64 一样吗?
编码算法一样,但 API 不同。浏览器用 atob/btoa,Node.js 用 Buffer。写同构代码用 TextEncoder/TextDecoder。
什么是 URL 安全的 Base64?
标准 Base64 中的 + 和 / 在 URL 里是保留字符。URL 安全的 Base64 把 + 换成 -,/ 换成 _,并去掉填充的 =。
如何在 Node.js 中解码 Base64?
字符串用 Buffer.from(base64String, 'base64').toString('utf-8'),原始二进制数据用 Buffer.from(base64String, 'base64')。
在线试试
不想写代码来编解码 Base64?试试我们的 免费在线 Base64 编解码工具 — 支持文本、文件和 Unicode。在浏览器中运行,无需上传服务器。