JavaScript 中 Base64 编解码完整指南
← 返回博客
JavaScript 中 Base64 编解码完整指南
· 5 分钟阅读
浏览器内置方法:btoa 和 atob
现代浏览器提供了两个全局函数用于 Base64 操作:btoa()(binary to ASCII,即编码)和 atob()(ASCII to binary,即解码)。这两个函数使用方便,无需引入任何库。
// 编码 / Encoding
const encoded = btoa('Hello, World!');
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="
// 解码 / Decoding
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
console.log(decoded); // "Hello, World!"
需要注意的是,btoa() 只接受 Latin-1(ISO-8859-1)字符,即每个字符的 Unicode 码点不超过 255。如果输入包含中文、表情符号或其他多字节 Unicode 字符,btoa() 会抛出 InvalidCharacterError 异常。这是初学者最常遇到的坑。
处理 Unicode 字符串
要对包含 Unicode 字符的字符串进行 Base64 编码,需要先将字符串转换为 UTF-8 字节序列,再进行 Base64 编码。现代浏览器可以使用 TextEncoder 完成这一步:
// 对 Unicode 字符串进行 Base64 编码
// Base64 encode a Unicode string
function encodeUnicode(str) {
const bytes = new TextEncoder().encode(str);
const binary = Array.from(bytes).map(b => String.fromCharCode(b)).join('');
return btoa(binary);
}
// 解码 Base64 为 Unicode 字符串
// Decode Base64 to Unicode string
function decodeUnicode(base64) {
const binary = atob(base64);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
console.log(encodeUnicode('你好,世界!'));
// "5L2g5aW977yM5LiW55WM77yB"
console.log(decodeUnicode('5L2g5aW977yM5LiW55WM77yB'));
// "你好,世界!"
Node.js 中的 Base64 编解码
Node.js 没有 btoa 和 atob(虽然较新版本已添加),传统上使用 Buffer 类来处理 Base64。Buffer 天然支持 UTF-8,不存在浏览器中 btoa 的 Unicode 限制。
// Node.js Buffer 方式
// Node.js Buffer approach
// 编码 / Encode
const text = '你好,World!';
const encoded = Buffer.from(text, 'utf8').toString('base64');
console.log(encoded);
// 解码 / Decode
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
console.log(decoded); // "你好,World!"
// 编码文件为 Base64
// Encode a file to Base64
const fs = require('fs');
const fileBuffer = fs.readFileSync('./image.png');
const base64Image = fileBuffer.toString('base64');
console.log(`data:image/png;base64,${base64Image}`);
Node.js v16+ 已在全局作用域中提供 btoa 和 atob,以保持与浏览器 API 的兼容性。但对于服务端应用,推荐仍使用 Buffer,因为它更灵活,能直接处理二进制数据流。
Base64URL 编解码
在处理 JWT Token 或需要将 Base64 放入 URL 的场景中,需要使用 Base64URL 变体。Base64URL 将 + 替换为 -,将 / 替换为 _,并去除填充字符 =。以下是浏览器中的实现:
// Base64URL 编码
// Base64URL encoding
function toBase64URL(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
// Base64URL 解码
// Base64URL decoding
function fromBase64URL(base64url) {
const base64 = base64url
.replace(/-/g, '+')
.replace(/_/g, '/');
// 补全填充 / Add padding
const padded = base64 + '=='.slice(0, (4 - base64.length % 4) % 4);
return atob(padded);
}
在 Fetch API 中使用 Base64
在使用 Fetch API 发送 HTTP 请求时,有时需要将 Base64 数据作为请求体发送,或者解码响应中的 Base64 数据。以下示例演示如何处理这两种场景:
// 发送包含 Base64 图片的 POST 请求
// Send POST request with Base64 image
async function uploadImageAsBase64(file) {
const reader = new FileReader();
const base64 = await new Promise((resolve) => {
reader.onload = (e) => resolve(e.target.result.split(',')[1]);
reader.readAsDataURL(file);
});
const response = await fetch('/api/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ image: base64 })
});
return response.json();
}
将 File 对象转换为 Base64
在浏览器中,用户通过 input[type=file] 选择的文件是一个 File 对象(Blob 的子类)。使用 FileReader API 可以将其转换为 Base64 字符串。这是前端处理文件上传并预览的常见模式:
// 将 File 转换为 Base64
// Convert File to Base64
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result); // data URI
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
// 使用示例 / Usage
const input = document.querySelector('input[type=file]');
input.addEventListener('change', async (e) => {
const file = e.target.files[0];
const dataURI = await fileToBase64(file);
document.querySelector('img').src = dataURI;
});
常见错误与调试
最常见的错误是 InvalidCharacterError: The string to be encoded contains characters outside of the Latin1 range,这是因为直接对包含中文等多字节字符的字符串调用 btoa() 导致的。解决方案是使用前面介绍的 TextEncoder 方法或 encodeURIComponent 技巧。
另一个常见问题是解码后得到乱码,通常是因为原始数据使用了 UTF-8 以外的字符集编码。在这种情况下,需要使用 TextDecoder 并指定正确的字符集名称,如 new TextDecoder('gbk') 用于解码简体中文 GBK 编码的数据。
立即尝试在线工具,无需安装,免费使用。
打开工具 →
立即免费使用相关工具
免费使用 →