iconv-lite 模块学习笔记
如果你的 node 项目中出现乱码问题,也许你可以仔细读一读这篇文章,否则可以略过以下部分以节约你的时间。
在学习这个模块之前,有必要先介绍下网络传输常识。
情景重现
当我们打开浏览器输入 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 举例:
代码中:
var buf1 = iconv.encode('我爱中国.', 'gbk'); var buf2 = iconv.encode('我爱中国.', 'utf8'); console.log('buf1 format of gbk: ', buf1); console.log('buf2 format of utf8: ', buf2);
打印结果:
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 数据可以看到是完全不一样的。
iconv-lite 的作用
Node.js 只有 utf8 编码规则,那么如果处理 gbk 编码规则的文件就会出现乱码情况,这一点在制作网络爬虫时经常遇到。
以客户端往服务端发送请求信息为例:
客户端发送请求时需要设置编码规则;
服务端在拿到客户端发送的请求信息时要按照相同的规则进行解码,将二进制数据转换为字符串。
iconv-lite 模块内置 gbk 规则和 utf8 规则,因此无论客户端发送请求时设置的编码规则是哪一个,服务端在接收客户端发送的请求信息时都可以正确解码。
tags:
安装
iconv-lite 为第三方模块,使用前需要先安装。
$ npm install iconv-lite
加码过程 —— encode( str, encoding)
作用: 将字符串转为 Buffer 数据
参数:
str:字符串,需要将该字符串转换为二进制的 Buffer 数据 encoding:编码规则,'utf8' 或者 'gbk' - 返回值:
如不了解 Buffer,可以查看第一章 Buffer 模块讲解。
- 示例代码:
新建文件 encode.js,内容如下:
var iconv = require('iconv-lite');
var buf1 = iconv.encode('我爱中国.', 'gbk');
var buf2 = iconv.encode('我爱中国.', 'utf8');
console.log('加码过程 format of gbk: ', buf1);
console.log('加码过程 format of utf8: ', buf2);
打印结果:
加码过程 format of gbk: <Buffer ce d2 b0 ae d6 d0 b9 fa 2e>
加码过程 format of utf8: <Buffer e6 88 91 e7 88 b1 e4 b8 ad e5 9b bd 2e>
结论: 编码规则不同,加码后返回的 Buffer 类型值也不相同。
解码过程 —— decode( buf, encoding)
作用: 将 Buffer 数据转换为字符串
参数:
buf:二进制 Buffer 数据 如不了解 Buffer,可以查看第一章 Buffer 模块讲解。
encoding:编码规则,'utf8' 或者 'gbk' - 返回值:
- 示例代码:
新建文件 decode.js,内容如下:
var iconv = require('iconv-lite');
// 创建一个 Buffer 类型的值
var buffers = new Buffer([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var str1 = iconv.decode(buffers, 'gbk');
var str2 = iconv.decode(buffers, 'utf8');
console.log('解码过程 format of gbk: ', str1);
console.log('解码过程 format of utf8: ', str2);
打印结果:
解码过程 format of gbk: hello
解码过程 format of utf8: hello
结论: 对于英文字母来说,gbk 和 utf8 处理规则一样;对于汉字来说,gbk 和 utf8 处理规则不同。