编码原理 · 解码过程 · HTML 实战展示
计算机中所有数据都以二进制(0 和 1)存储。图片文件本质上是一长串字节(bytes),每个字节 8 位(bit)。
Base64 的核心思想:把任意二进制数据,用 64 个可打印的 ASCII 字符来表示。这样原本不可直接嵌入文本的二进制数据,就可以安全地在纯文本环境(HTML、CSS、JSON、XML、邮件等)中传输。
=假设有 3 个字节的原始数据:01001101 01100001 01101110(即 ASCII "Man")
| 步骤 | 操作 | 结果 |
|---|---|---|
| 原始 3 字节 | 01001101 01100001 01101110 |
77 97 110(十进制) |
| 连成 24 bits | 010011010110000101101110 |
— |
| 切成 4 个 6-bit | 010011 / 010110 / 000101 / 101110 |
19 22 5 46 |
| 查 Base64 表 | 19→T, 22→W, 5→F, 46→u | TWFu |
当原始字节数不是 3 的倍数时,需要用 = 补齐:
| 剩余字节数 | 编码后字符数 | 等号数量 | 示例 |
|---|---|---|---|
| 1 字节 | 4 个字符 | 2 个 = | TQ== |
| 2 字节 | 4 个字符 | 1 个 = | TWE= |
| 3 字节 | 4 个字符 | 0 个 | TWFu |
每 3 个原始字节 → 4 个 Base64 字符,所以编码后体积膨胀约 33%(4÷3 ≈ 1.33)。
例如:一张 150 KB 的 PNG 图片,Base64 编码后字符串大约 200 KB。
=浏览器提供了两个内置 API 来完成编解码,无需手写算法:
// ========== 编码:图片文件 → Base64 字符串 ==========
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();
reader.onload = (e) => console.log(e.target.result);
reader.readAsDataURL(file); // → data:image/png;base64,iVBORw0KG...
// ========== 解码:Base64 字符串 → 二进制数据 ==========
const base64 = "iVBORw0KGgo..."; // 去掉 "data:image/png;base64," 前缀
const raw = atob(base64); // Base64 → 二进制字符串
const bytes = new Uint8Array(raw.length);
for (let i = 0; i < raw.length; i++) {
bytes[i] = raw.charCodeAt(i); // 得到每个字节的数值
}
// 用 bytes 创建 Blob:
const blob = new Blob([bytes], { type: 'image/png' });
| API | 方向 | 说明 |
|---|---|---|
btoa() | 字符串 → Base64 | Binary to ASCII |
atob() | Base64 → 字符串 | ASCII to Binary |
FileReader.readAsDataURL() | 文件 → Data URL | 自动生成完整 data:... 前缀 |
HTML 通过 Data URI(数据统一资源标识符) 直接内嵌 Base64 图片数据,无需额外的 HTTP 请求。
格式:
data:[<MIME 类型>][;base64],<Base64 数据>
示例:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
<img> 标签的 src 属性<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA..."
alt="Base64 图片"
/>
background-image.icon {
width: 32px; height: 32px;
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0...");
}
<canvas> 动态绘制const img = new Image();
img.onload = () => ctx.drawImage(img, 0, 0);
img.src = "data:image/png;base64,...";
| 图片格式 | MIME 类型 | Data URI 前缀 |
|---|---|---|
| PNG | image/png | data:image/png;base64, |
| JPEG | image/jpeg | data:image/jpeg;base64, |
| GIF | image/gif | data:image/gif;base64, |
| WebP | image/webp | data:image/webp;base64, |
| SVG | image/svg+xml | data:image/svg+xml;base64, |
| BMP | image/bmp | data:image/bmp;base64, |
| ICO | image/x-icon | data:image/x-icon;base64, |
下面这张 1×1 像素的红色 PNG 图标完全内嵌在 HTML 中(Base64):
↑ 放大到 200×200 的纯红色 PNG(原始 1×1 像素)
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4
AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEA
mpwYAAAA/klEQVR4nO2UMQ7CMAxFXcROD8DAxMjcBT
FxG5ZOwsjC0pEzcAFYGNkYGFCYqhoJqWqwFYfuUf6T
rL8cxxIkgkwZAL4ARC+XGzq/A+AOwAOAEYALAGYA4
lC0ZwBSEXyk0PcehH7JOFr33kEpZbmjKYq3nnkfWO
ckENoEYAvUI5JzgCxwGqF7JfAtVixbsY0pYxPboEl
C0hP4X0SF9kVXQBRW1xui1cBdENfCK8B8FFoo0REQ
dbndLnCWAwwACNQ3gsgFaDWBOKctP/GL4AtAfV7PD
hC1/3OPWAbfKfw4gf1JpB79zFe4v1IsLsDXo5Z4AI
f2VH43yGLcAC8AriTcNXWxL1FGH3FV88D9AAAAAEl
FTkSuQmCC
📁
点击或拖拽图片到这里
支持 PNG / JPG / GIF / WebP / SVG 等格式
| ✅ 优点 | ❌ 缺点 |
|---|---|
| 减少 HTTP 请求数(小图标场景) | 体积膨胀约 33% |
| 无需额外文件管理,一切内嵌 | HTML / CSS 文件变大,影响首屏加载 |
| 适合邮件、JSON 等纯文本场景 | 浏览器无法单独缓存 Base64 图片 |
| 跨域无限制(不需要 CORS) | 修改图片需要重新编码,维护困难 |