几乎每个开发者第一次发现 Base64 时都会产生同一个念头:
“等等,我能把整个文件变成文字?”
能。
图片可以变成文字,PDF 可以变成文字,小图标可以变成一堵像键盘从楼梯滚下去后留下的字符墙:
iVBORw0KGgoAAAANSUhEUgAA...看起来像魔法,其实只是编码。
而且要付费。不是银行卡扣款,是体积和内存扣款。
电脑本来就认识二进制文件
JPEG、PDF、MP3 本质上都是字节。电脑完全不需要 Base64 才能理解它们。Base64 真正有价值的地方,是当二进制数据需要穿过偏好文本的环境,比如 JSON、某些协议、HTML/CSS 嵌入、Data URL 或特定 API。
为什么叫 Base64
常见 Base64 字符表有 64 个符号:A-Z、a-z、0-9,再加两个符号。64 恰好是 2^6,因此一个 Base64 字符承载 6 bit。
普通字节是 8 bit。于是经典转换变成:
3 bytes = 24 bits
24 bits = 4 Base64 characters这也直接带来最著名的副作用。
它会变大,大约三分之一
3 个字节变成 4 个字符,基础开销约为:
4 / 3 ≈ 1.33也就是大约 33%。3 MB 的原始数据,Base64 表示可能接近 4 MB,外面再包 JSON 或其他结构还会继续增加。
网络压缩有时能减轻传输上的实际损失,但编码本身并没有凭空变瘦。
Data URL 为什么看起来特别神
<img src="data:image/png;base64,iVBORw0...">这里没有单独的图片 URL,图片内容直接塞进了地址。对于非常小的图标、占位图或自包含文档,这很方便。
但把一张巨大照片整个放进 HTML,会让页面源码长成考古现场。调试时连引号到底在哪结束都开始成为探索活动。
浏览器里真正危险的是“同时存在好几份”
用户选了一张 8 MB JPEG。应用读取它,转成 Base64,生成预览,又画进 Canvas。此时内存里可能同时有:
- 原始 File / Blob。
- 读取出来的二进制缓冲。
- Base64 字符串。
- 解码后的像素。
- Canvas 或缩略图副本。
JPEG 文件很小,是因为它被压缩过。真正解码成像素后,一张 4000 × 3000 的 RGBA 图片理论上就可能需要约:
4000 × 3000 × 4 = 48,000,000 bytes还没算别的副本。
所以桌面电脑上“毫无问题”的图片处理,到了手机上可能突然卡死,并不神秘。你的 8 MB 照片在内存里开了同学会。
只做预览时,Blob URL 往往更合适
const url = URL.createObjectURL(file);
image.src = url;用完后:
URL.revokeObjectURL(url);浏览器可以引用现有 Blob,不必为了显示预览先造一个巨大 Base64 字符串。少一次复制,就少一点内存烟花。
Base64 不是加密
这一条值得加粗:
Base64 不提供保密性。
hello 编码后可能是 aGVsbG8=,看起来更神秘,但任何人一秒就能还原。
编码是改变表示方式。加密才是依靠密钥保护内容。
如果密码写在源码里,只是套了一层 Base64,那它仍然是写在源码里的密码,只不过戴了副墨镜。
什么时候适合用
- API 明确要求 Base64。
- 二进制必须嵌进文本格式。
- 资源非常小,适合 Data URL。
- 协议本身定义了 Base64 表示。
而大文件上传、视频、批量图片、长期存储等场景,通常更适合 Blob、multipart/form-data 或流式传输。
最后
Base64 不压缩文件,不加密文件,也没有把数据变成某种神秘互联网物质。
它只是把二进制内容改写成一组受限制的文本字符。
非常实用。
代价也非常明确。
下次看到 JSON 里躺着一万多字符的图片时,不用慌。
PNG 只是穿了一套很贵的衣服。