前端进阶-个人笔记-学习Base64编码

本文详细解读Base64编码的工作原理,如何在浏览器和Node.js中实现转换,并介绍其在邮件传输、HTTP2、加密输出、图片显示及Webpack中的应用场景。讨论了Base64编码的特点和优化注意事项。
摘要由CSDN通过智能技术生成

前言
 Base64 是一种基于 64 个可打印字符来表示二进制的表示方法。具体的 64 个字符如下图所示:

在这里插入图片描述
出现背景

早期邮件传输协议基于 ASCII 文本,对于诸如图片、视频等二进制文件处理并不好。

ASCII 主要用于显示现代英文,到目前为止只定义了 128 个字符,包含控制字符和可显示字符。

为了解决上述问题,Base64 编码顺势而生。

基础使用

在浏览器环境下,可以使用 window.atob 和 window.btoa 方法,进行 Base64 和 UTF-8 之间的转化:

  const utf8ToBase64 = window.btoa('Hello World!');  
  console.log(utf8ToBase64); // base64: SGVsbG8gV29ybGQh 
  const base64ToUtf8 = window.atob(utf8ToBase64);  
  console.log(base64ToUtf8); // UTF-8: Hello World!

在 Node.js 环境下,可以通过 Buffer 来完成两者之间的转化:

  const strToBase64 = Buffer.from('Hello World!', 'utf-8').toString('base64');  
  console.log('base64: ', strToBase64); // base64:  SGVsbG8gV29ybGQh
  const str = Buffer.from(strToBase64, 'base64').toString('utf8');
  console.log('utf-8: ', str) // utf-8:  Hello World!

实现原理

Base64 编码的过程如下:

  1. 首先对待编码字符串进行每 3 个字节分组,如果当前分组不够 3 个字节,则通过补零来构成 3 字节一组。
  2. 将每组的 24 位按照 6 位划分,得到 4 个 6 位二进制数组。
  3. 对每个 6 位二进制数组进行高位补零,形成 8 位二进制数数组。
  4. 查表获取每个字节的十进制对应的字符。
  5. 将(1)中补充的字节数兑换成 = 的个数,拼接到(4)得到的完整字符串的尾部。

以 a 字符为例。

a 对应 1 个字节,如果要完成分组,那么就需要用零补足两个字节:

  0 1 1 0 0 0 0 1  
  ----------------  
  0 0 0 0 0 0 0 0  
  ----------------  
  0 0 0 0 0 0 0 0

接下来需要将它们再按照 6 位划分:

  0 1 1 0 0 0  
  -----------  
  0 1 0 0 0 0  
  -----------  
  0 0 0 0 0 0  
  -----------  
  0 0 0 0 0 0

再进行高位补零补足 8 位,形成一个字节:

  0 0 0 1 1 0 0 0 --> 24  
  ---------------  
  0 0 0 1 0 0 0 0 --> 16  
  ---------------  
  0 0 0 0 0 0 0 0 --> 0  
  ---------------  
  0 0 0 0 0 0 0 0 --> 0

再根据每个字节的十进制值查表,得到字符串 YQ,由于用零补充了两个字节,所以加上两个 = ,那么最终转化的结果为:

  YQ==

特点

从上述实现原理中,可总结出 Base64 编码的几个特点:

  • Base64 编码结果的长度永远是 4 的整数倍。
  • Base64 编码结果至多包含两个 = 字符。
  • Base64 编码使原文的大小增加了 1/3 倍。

应用场景

Base64 编码的第一种应用场景就是前面提到的邮件传输协议,不过随着时代的发展,邮件传输协议已经支持直接传输二进制数据,不再需要 Base64 或者其它编码方式。

HTTP2 也改进为二进制格式传输数据,使得协议解析起来更加高效。

第二种应用场景:加密内容的输出。
  客户端在发起请求时,通常需要将内容进行加密处理,而最终加密输出的内容就是 Base64 编码格式。这里有一个特别需要注意的地方,当标准 Base64 编码的内容放在 URL 中传输的时候会出特殊的情况导致服务端解密失败。

URL编码器会把标准 Base64 编码中的 “/” 和 “+” 字符变为形如 “%XX” 的形式。

所以客户端一般会将标准 Base64 编码中的 + 和 / 替换为 URL 安全的字符,例如 - 和 _ 。
  第三种应用场景:图片资源的显示。
  在浏览器环境下,不仅可以通过标准的 HTTP 或者 HTTPS 链接来显示图片,还可以通过 Data URLs 来显示图片:

  <img src="data:image/gif;base64,R0lGODlhMwAxAIAAAAAAAP///  
  yH5BAAAAAAALhbstxgzADEAAAK8jI+pBr0PowytzotTtbm/DTqQ6C3hGX  
  ElcraA9jIr66ozVpM3nseUvYP1UEHF0FUUHkNJxhLZfEJNvol06tzwrgd 
  LbXsFZYmSMPnHLB+zNJF1215+SOf50+6rG7lKOjwV1ibGdhHYRVYVJ9Wn  
  k2HWtLdIWMSH9lfyODZoZTb4xdnpxQSEF9oyOWIqp6gaI9pI1Qo7BijbF  
  ZkoaAtEeiiLeKn72xM7vMZofJ23zJys2UxsCT3kO229LH1tXAAAOw==">

webpack 中的 url-loader 就提供了将图片转化为 Data URLs 的功能,一般会设置图片的大小限制,这主要是因为 Base64 处理之后的大小会增加 1/3 倍,所以图片太大的话,反而得不偿失。

  这种将图片内联到 HTML 或者 CSS 的方式,可以有效地减少请求数量,从而优化站点的网络请求。
  
  但是该方式也存在缺陷:

  • 体积增大,需要权衡对 HTML 和 CSS 的影响。
  • 无法充分利用缓存,依赖其内联的 HTML 和 CSS 文件的缓存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值