约 7 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
它做的事只有一件:把任意 3 字节重排成 4 个可打印字符(A-Z a-z 0-9 + /),让二进制能安全穿过「只认文本」的通道(JSON 字段、邮件、URL)。任何人拿到 Base64 都能瞬间还原——需要保密请用加密,Base64 只负责「安全运输」。
btoa 的输入按 Latin-1(每字符 1 字节)理解,中文字符超出该范围直接抛错;有人用 charCodeAt 硬凑,产出的是错误字节序列,解码回来就是乱码。正确做法:先 UTF-8 编码成字节,再对字节做 Base64。
btoa("中文")
// InvalidCharacterError(或产出无法还原的字节)const bytes = new TextEncoder().encode("中文");
const b64 = btoa(String.fromCharCode(...bytes));
// 解码反向:
const bin = atob(b64);
const txt = new TextDecoder().decode(Uint8Array.from(bin, c => c.charCodeAt(0)));
// → "中文"标准 Base64 字母表含 + 和 /,而 + 在 URL 查询串的历史语义是空格:服务端做一次 URL 解码,token 里的 + 全变成空格,校验直接失败。这正是 JWT 用 base64url 的原因。修复二选一:传输前整体 encodeURIComponent;或直接换 URL 安全变体。
const urlSafe = b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); const back = urlSafe.replace(/-/g, "+").replace(/_/g, "/");
| 变体 | 第 62 / 63 位字符 | 填充 | 适用 |
|---|---|---|---|
| 标准 Base64 | + 和 / | = 有 | JSON 字段、邮件、MIME |
| Base64url | - 和 _ | = 可留可去 | URL / Cookie / JWT / 文件名 |
3 字节变 4 字符,膨胀率恒定 4/3 ≈ 133%,再算上 data:image/png;base64, 前缀。小图标内嵌没问题(省一次请求),但把几百 KB 的图内嵌进 HTML/CSS/JS,等于让每个访客多下三分之一的流量,还会错失缓存。经验值:2 KB 以下考虑内嵌,更大的图老老实实用文件 + 缓存头。体积与编码互转可以直接用 <a class="faq-link" href="/tools/image-to-base64/">图片转 Base64 工具</a>核对。
原始字节数除以 3 的余数决定补几个 =:余 1 补两个,余 2 补一个,整除不补。因此去掉 = 也能无损还原(长度 mod 4 可推算),JWT 就去掉了 padding;但混用场景要小心——有的校验器严格要求 padding,有的拒绝 padding,传输两端先对齐约定。判断一段 Base64 长度是否合法:去掉 = 后,长度 mod 4 的余数必须与 padding 数量自洽。
// Blob/File → base64(异步)
const b64 = await new Promise((res, rej) => {
const r = new FileReader();
r.onload = () => res(r.result.split(",")[1]); // 去掉 data:...;base64, 前缀
r.onerror = rej;
r.readAsDataURL(blob);
});
// base64 → Blob
const bin = atob(b64);
const bytes = Uint8Array.from(bin, c => c.charCodeAt(0));
const blob2 = new Blob([bytes], { type: "image/png" });JWT 用 base64url:+ 换成 -、/ 换成 _、去掉 = 填充。因为 JWT 出现在 URL、Cookie 和 HTTP 头里,标准字母表的 + / = 都有特殊含义,直接放会被改写。互转规则就一行 replace,可以用 Base64 编解码工具实际验证。
绝对不能。Base64 没有密钥、没有混淆,任何人拿到的就是原文的另一种写法,一行代码即可还原。密码要存就先加盐哈希(bcrypt / argon2),传输要保密就走 TLS。
三处常见断点:① data URI 前缀不完整或 MIME 类型写错(image/jpg 应为 image/jpeg);② Base64 串里混入了换行或空格(从邮件 / PDF 复制时常见);③ CSS url() 里的引号把串截断了。先把编码结果粘进工具里「解码回预览」看图能不能出来,能出来就是引用端的问题。
膨胀率是数学决定的:3 字节重排成 4 字符(4/3 ≈ 133%),再算上 data URI 前缀。无法避免,只有替代方案:大文件走二进制通道(multipart、原始字节流),URL 场景用 base64url 并配合 gzip(Base64 字符集熵低,压缩能收回一部分)。2 KB 以下内嵌、更大走文件 + 缓存,是性价比分界线。