Base64 是一种在网络中存储和传输二进制数据的常见方式。它使用每个字节的前两位固定为 0,剩下的 6 位用来表示数据,因此每个字节可以表示 64 种不同的情况。
看到这里,相信大家都能意识到,这种编码格式无法充分利用存储资源,效率较低。那么,为什么它在网络中仍然如此普遍呢?
其实,Base64 最早是用于邮件传输协议的。当时,邮件传输协议只支持 ASCII 字符,这意味着只能使用 ASCII 码表示所有英文字符、数字以及一些符号。存在一个问题,如果邮件仅传输英文字符和数字,那么 ASCII 是可以直接支持的。但在传输图像、视频等资源时,这些资源转换为 ASCII 后会出现非英文字符的情况。此外,邮件中往往还有许多控制字符,而这些控制字符通常是不可见的。在传输过程中,非英文字符和控制字符很容易导致错误,从而影响邮件的正常传输。为了解决这个问题,出现了一种新的编码规则,即将二进制数据按每三个字节分组,然后将这三组字节(共24位)转换为四组6位数据,每组6位通过查表对应一个 ASCII 符号,这就是Base64 编码。
Base64 编码表
Base64 将 8 位的字节数据分解成 6 位一组的二进制片段。每个 6 位的片段对应Base64 编码表中的一个字符。例如,字符 M 的 ASCII 码是 77,将其转换为二进制后,前六位的值是 19,对应Base64 字典中的字符 T。
当然,这里会遇到一个问题。如果需要编码的二进制数据不是 3 的倍数,那么最后会剩下 1 到 2 个字节。为了解决这个问题,Base64 会在末尾用 000000字节进行补齐,使得总字节数能够被 3 整除。补齐的部分用 "=" 符号表示,等号的数量反映了补了多少字节,并且在解码时会自动去掉。总体来说,经过Base64 编码后,字符数量比编码前增加了大约 33%。
图片的Base64 编码形式
我们之前提到过,Base64 编码是当前网站上加载小图片的主要方式。那么,Base64 是如何处理图像的呢?
我们都知道,在网页中使用图像通常采用 img 标签,而 img 标签的 src 属性则指向远程服务器上的资源。当网页加载到浏览器时,浏览器会为每个外部资源向服务器发送请求以获取资源。然而,这种方式会消耗大量网络资源,并且大多数浏览器对并发请求数量有限制。如果网页中嵌入了过多的外部请求,就会导致页面加载速度变慢。
Base64 编码利用 Data URL 技术,可以将图片以字符串形式直接嵌入到页面中,使其与 HTML 紧密结合。这样,在加载时就能避免对外部资源的请求。
为什么选择数据 URL?
关于选择 Data URL 技术的原因,主要是因为它相较于传统的外部资源引用方式,具有以下几项优势:
减少 HTTP 请求数量。
避免出现跨域问题。
可以像独立的图片一样使用,例如作为背景图片进行重复使用等。
通过这种方式,Base64 编码能更快速、便捷地优化前端的各种图片资源。下面我们来看一个具体例子:
可以清楚地看到,Base64 编码将图片数据转换为一串字符串,并用这个字符串来替代图像的地址。虽然从表面上看这段字符串似乎与图片没有任何关联,但最终渲染出来的却是一幅完整的图像。
当然,使用数据网址进行Base64 图片编码并不是完全理想的,它存在两个明显的缺点:
Base64 编码的数据体积通常是原始数据的 4/3 倍,因此以 Data URL 形式存在的图片,其体积比二进制格式的图片大 1/3。
数据 URL格式的图片不会被浏览器缓存。
无法在浏览器中缓存的意思是每次访问时都需要重新请求资源,这对服务器造成了较大的压力。那么,有没有办法将这些数据也存放在浏览器缓存中呢?
提高加载速度的小技巧
实际上,大多数网站的背景图是由一个几像素大小的小图片构成的,通过平铺的方式形成背景。通常,我们会将这个小图片保存为 GIF 或 PNG 格式,然后在 CSS 的 background-image 属性中引用该图片的地址。不过,浏览器并不关心 URL中的内容,只需要通过它获取所需的数据。
我们可以利用 CSS 样式文件,将以 Data URL 形式的图片存储在 CSS 中。这样,浏览器在缓存 CSS 文件时,也会同时缓存这些图片,从而进一步提升页面的加载速度。
base32编码表
Base32编码是一种将二进制数据转换为可打印字符的编码方式,常用于数据通信和数据存储。以下是Base32编码表的部分内容:
字符 | 值(十进制) | 字符 | 值(十进制)
------------|-----------------|-------------|-----------------
A | 0 | N | 56
B | 1 | O | 57
C | 2 | P | 58
D | 3 | Q | 59
E | 4 | R | 60
F | 5 | S | 61
G | 6 | T | 62
H | 7 | U | 63
I | 8 | V | 64
J | 9 | W | 75 (注:W之后的字符在标准Base32编码中不再使用)
K | 10 | 未使用字符无相应值