Javascript的编码和解码

为什么需要编码和解码

编码是为了符合传输的要求,解码是为了还原成我们能识别的信息。 例如字符编解码,字符编码在一系列数字与人们将文本输入到计算机中时希望看到的字符之间提供映射。 因为世界上有不同的语言和文字,所以需要将不同的文字编码以通过计算机处理和传输。 再比如多媒体编解码,因为有多种不同格式的图像声音,所以它们各自有自己编解码标准。

ASCII 码、非 ASCII 编码、Unicode和UTF-8

具体请查看这篇文章:阮一峰 - 字符编码笔记:ASCII,Unicode 和 UTF-8

为了保证传递数据的统一性,那么就需要对传递数据进行编码。在前端里使用最多的场景就是,当网址作为参数传递的时候,就需要进行编码。

Javascript中的编码和解码方法

编码说明解码说明
encodeURI(URI)通过转义某些字符对 URI 进行编码decodeURI(encodedURI)对使用 encodeURI() 方法编码的字符串进行解码
encodeURIComponent(str)通过某些转义字符对 URI 的组件进行编码decodeURIComponent(encodedURI)对使用 encodeURIComponent() 方法编码的字符串进行解码
btoa(stringToEncode)字符串或二进制值转为 Base64 编码。atob(encodedData)把 Base64 编码转为原来的字符。

escape(str) 和 unescape(str) 已经废弃,不再使用。

encodeURI

encodeURI 会替换所有的字符,但不包括以下字符,即使它们具有适当的UTF-8转义序列:

类型包含
保留字符;  ,  /  ?  :  @  &  =  +  $
非转义的字符字母  数字  -  _  .  !  ~  *  '  (  )
数字符号#

请注意, encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 "&", "+", 和 "=" 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。所以请使用 encodeURIComponent 方法。

const url = 'http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor'
const str = encodeURI(url)
console.log(str)
// 结果:http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor

decodeURI

const encodeStr = '%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%92%8C%E5%9B%BD'
const str = decodeURI(encodeStr)
console.log(str)
// 结果:中华人民共和国

encodeURIComponent

encodeURIComponent  转义除了如下所示外的所有字符: A-Z  a-z  0-9  -  _  .  !  ~  *  '  (  )

encodeURIComponent  和 encodeURI  有以下几个不同点:

var set1 = ";,/?:@&=+$";  // 保留字符
var set2 = "-_.!~*'()";   // 不转义字符
var set3 = "#";           // 数字标志
var set4 = "ABC abc 123"; // 字母数字字符和空格

console.log(encodeURI(set1)); // ;,/?:@&=+$
console.log(encodeURI(set2)); // -_.!~*'()
console.log(encodeURI(set3)); // #
console.log(encodeURI(set4)); // ABC%20abc%20123 (the space gets encoded as %20)

console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24
console.log(encodeURIComponent(set2)); // -_.!~*'()
console.log(encodeURIComponent(set3)); // %23
console.log(encodeURIComponent(set4)); // ABC%20abc%20123 (the space gets encoded as %20)

decodeURIComponent

const encodeStr = '%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%92%8C%E5%9B%BD'
const str = decodeURIComponent(encodeStr)
console.log(str)
// 结果:中华人民共和国

什么是base64

Base64编码,就是说选出64个字符:小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符),作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

  • 第一步,将每三个字节作为一组,一共是24个二进制位。
  • 第二步,将这24个二进制位分为四组,每个组有6个二进制位。
  • 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
  • 第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。

btoa & atob

let encodedData = window.btoa("Hello, world"); // 编码
let decodedData = window.atob(encodedData);    // 解码
console.log(encodedData) // SGVsbG8sIHdvcmxk
console.log(decodedData) // Hello, world

参考文章