关于乱码问题的机理分析
作者: dkvirus 发表于: 2018-06-25 15:41:00 最近更新: 2018-08-01 22:09:04

一、情景重现

  • 当我们打开浏览器输入 www.baidu.com 时,这时由客户端(也就是浏览器)往服务器(也就是百度公司的超级电脑)发送一条请求信息

  • 百度公司的超级电脑接收到请求后,给予响应,响应信息里就包含了百度首页的页面;

  • 当客户端(浏览器)接收到响应后,将响应信息里包含的百度首页页面渲染一下,然后我们才能看到百度的页面。

二、网络只能传输二进制数据

  • 请求信息响应信息其实可以看成就是一个字符串,里面描述着要怎么怎么做;

  • 请求信息响应信息是需要在网络中进行传递的,而网络不认识字符串,只认识 0 和 1 这种二进制数据,所以在发送请求信息响应信息之前都有一个步骤就是先将信息转换为二进制的 Buffer 数据,在接收到信息的时候再转换为字符串;

    以客户端往服务端发送请求信息为例:

    • 客户端发送请求时需要设置规则;

    • 服务端在拿到客户端发送的请求信息时要按照相同的规则进行解码,将二进制数据转换为字符串。

      请求/响应

  • 将字符串与二进制进行转换是遵循一定规则,也就是我们常说的编码

三、编码就是规则

  • 我们经常会听到 gbk 编码,utf 编码,什么是编码呢?上面已经提到请求信息和响应信息在网络中传输需要先转换为二进制 Buffer 数据,但是各个国家转换的规则是不同的,天朝有自己的规则 gbk,而国际上统一推出了 utf8 的规则。

  • 这就好比对于 '111223' 这个字符串,天朝的规则 gbk 转换为二进制可能是 1*3+2*2+3,而国际规则 utf8 转换为二进制可能是 1^3 +2^2+3(这里只是举例,实际情况并不是如此),而在接收到信息时将信息解码为字符串时还需要使用对应的规则才能得到正确的结果。

  • 如果在编码为二进制时使用 gbk 编码,而解码为字符串时使用 utf8 编码,由于生成规则和解码规则不同,就会导致乱码。

  • Node 中将字符串转换为 Buffer 举例:

    • 代码中:

      1
      2
      3
      4
      var buf1 = iconv.encode('我爱中国.', 'gbk');
      var buf2 = iconv.encode('我爱中国.', 'utf8');
      console.log('buf1 format of gbk: ', buf1);
      console.log('buf2 format of utf8: ', buf2);
    • 打印结果:

      1
      2
      buf1 format of gbk:  <Buffer ce d2 b0 ae d6 d0 b9 fa 2e>
      buf2 format of utf8: <Buffer e6 88 91 e7 88 b1 e4 b8 ad e5 9b bd 2e>
    • 结论:
      同样的字符串 “我爱中国”,使用 gbk 和 utf8 两种规则转换的 Buffer 数据可以看到是完全不一样的。

首页
友链
归档
dkvirus
动态
RSS