原生 JS 支持 Base64 编解码

原生 JS 支持 Base64 编解码

前几天做某个功能的时候出于某个特殊需求,需要将 URL 进行 Base64 编码传给后端。本来计划找个开源的 Base64 库,后面机缘巧合发现 JS 本身也支持 Base 64 编解码。

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation.

btoa()

btoa() 方法是将字符串进行 Base64 编码,也就是 Binary To ASCII。

1
btoa('JS'); // "SlM="

atob()

atob() 方法对 Base64 编码后的 ASCII 码进行解码,即 ASCII To Binary。

1
atob('SlM='); // 'JS'

其它

  • Unicode 问题

    如果待编码的字符串超过了 8 位 ASCII 编码的字符范围时,调用 btoa() 方法会抛出 Character Out Of Range 异常。有两种解决方法:

    • 先转义(escape)后编码

      1
      2
      3
      4
      5
      6
      7
      const b64EncodeUnicode = (str) => {
      return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => {
      return String.fromCharCode('0x' + p1);
      }));
      };

      b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
      1
      2
      3
      4
      5
      6
      7
      const b64DecodeUnicode = (str) => {
      return decodeURIComponent(atob(str).split('').map((c) => {
      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
      }).join(''));
      };

      b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
    • 将 UTF-16 转换为 UTF-8 再编码

      使用 TextEncodingTextEncoderLiteBuffer 等开源库配合 base64-js 一起使用。

      1
      2
      3
      4
      5
      const Base64Encode = (str, encoding='utf-8') => {
      let bytes = new (TextEncoder || TextEncoderLite)(encoding).encode(str);

      return base64js.fromByteArray(bytes);
      }
      1
      2
      3
      4
      5
      const Base64Decode = (str, encoding='utf-8') => {
      let bytes = base64js.toByteArray(str);

      return new (TextDecoder || TextDecoderLite)(encoding).decode(bytes);
      }

参考