Nodejs request库使用时, gb2312、GBK中文乱码解决方法

Nodejs request库使用时, gb2312、GBK中文乱码解决方法

使用http库或者request库请求一个url地址时,中文全部乱码了。弄了好久,问题终于解决了,下面给出解决方案,

iconv需要依赖native库,这样一来,在一些不支持native模块安装的虚拟主机和windows平台上,我们还是无法安心处理GBK编码。 需要引入三个库 request、iconv-lite、bufferhelper

中文问题完美解决

/**
 * [@param](/user/param) url 需要抓取的url地址
 * [@param](/user/param) calback
 */
function fetchContent(url,calback){
    var req = request(url, {timeout: 10000, pool: false});
    req.setMaxListeners(50);
    req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36')
        .setHeader('accept', 'text/html,application/xhtml+xml');
req.on('error', function(err) {
    console.log(err);
});
req.on('response', function(res) {
    var bufferHelper = new BufferHelper();
    res.on('data', function (chunk) {
        bufferHelper.concat(chunk);
    });
    res.on('end',function(){
        var result = iconv.decode(bufferHelper.toBuffer(),'GBK');
        calback(result);
    });
});

}

#介绍下GBK编码 Unicode是全世界通用编码 UTF8,UTF16,UTF32只是Unicode的实现方式之一。UCS2是UTF16的子集,UCS2编码中每个Unicode使用两个字节编码,高字节在高位。Node.JS支持Buffer.toString(‘UTF8’)和Buffer.toString(‘UCS2’)。 GBK也是Unicode的实现方式之一,总共23940个编码,

UTF8与GBK进行转换,可以把Unicode作为中间编码。 UTF8编解Unicode规则简单,参见 UTF8 GBK编解Unicode无特定规则,一般可通过查表方式 GBK兼容ascii码,ascii字符用一字节编码,最高位为0,其它字符用两位编码,高字节从0x81。编解码时通过此规律对单字节和双字节字符加以区分。由此可见,GBK是单字节、双字节变长编码。 理解了上面几点后,编解码GBK文件其实只需要一个GBK–>Unicode的码表就够了。GBK编码时,通过Unicdoe–>GBK,生成相应的GBK字节流;GBK解码时,通过GBK–>Unicode,生成UCS2字节流,再通过buffer.toString(‘UCS2’)即可转换成string对象。

npm install iconv-lite

var iconv = require(‘iconv-lite’);

var str = iconv.decode(buf, ‘GBK’); //return unicode string from GBK encoded bytes

var buf = iconv.encode(str, ‘GBK’);//return GBK encoded bytes from unicode string


7 回复

感谢分享


Nodejs request库使用时, gb2312、GBK中文乱码解决方法

在使用http库或者request库请求一个URL地址时,经常会遇到中文乱码的问题。本文将提供一种解决方案,以帮助你在使用Node.js处理GBK编码的网页时避免乱码问题。

解决方案

为了正确处理GBK编码的网页,我们需要引入以下三个库:

  • request:用于发起HTTP请求。
  • iconv-lite:用于编码和解码。
  • bufferhelper:用于处理数据缓冲区。

以下是具体的实现代码:

const request = require('request');
const iconv = require('iconv-lite');
const BufferHelper = require('bufferhelper');

/**
 * @param url 需要抓取的url地址
 * @param callback 回调函数
 */
function fetchContent(url, callback) {
    const req = request(url, { timeout: 10000, pool: false });
    req.setMaxListeners(50);
    req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36')
        .setHeader('accept', 'text/html,application/xhtml+xml');

    req.on('error', function (err) {
        console.log(err);
    });

    req.on('response', function (res) {
        const bufferHelper = new BufferHelper();
        res.on('data', function (chunk) {
            bufferHelper.concat(chunk);
        });

        res.on('end', function () {
            const result = iconv.decode(bufferHelper.toBuffer(), 'GBK');
            callback(result);
        });
    });
}

介绍GBK编码

GBK是一种双字节变长编码方式,兼容ASCII码。它主要用于中文字符的编码,总共有23940个编码。

  • GBK编码特点

    • ASCII字符用一字节编码,最高位为0。
    • 其他字符用两位编码,高字节从0x81开始。
  • 编解码规则

    • 编码时,通过Unicode到GBK的映射表生成GBK字节流。
    • 解码时,通过GBK到Unicode的映射表生成UCS2字节流,再通过buffer.toString('UCS2')转换成字符串。

安装依赖

首先确保你已经安装了所需的库:

npm install request iconv-lite bufferhelper

示例代码

const request = require('request');
const iconv = require('iconv-lite');
const BufferHelper = require('bufferhelper');

function fetchContent(url, callback) {
    const req = request(url, { timeout: 10000, pool: false });
    req.setMaxListeners(50);
    req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36')
        .setHeader('accept', 'text/html,application/xhtml+xml');

    req.on('error', function (err) {
        console.log(err);
    });

    req.on('response', function (res) {
        const bufferHelper = new BufferHelper();
        res.on('data', function (chunk) {
            bufferHelper.concat(chunk);
        });

        res.on('end', function () {
            const result = iconv.decode(bufferHelper.toBuffer(), 'GBK');
            callback(result);
        });
    });
}

fetchContent('http://example.com', function (content) {
    console.log(content);
});

通过上述代码,你可以正确地处理GBK编码的网页内容,并避免乱码问题。

有人写了个叫 gbk 的库,可以直接请求GBK编码的网页:https://npmjs.org/package/gbk

感觉复杂了…如果认真阅读一下request 的源码的话会发现


        var response = function (err, response, body) {
                   //返回的body 直接就是buffer 了...
                var buf =  iconv.decode(body, 'gb2312');
        }

request.get({ url : url , encoding : null //让body 直接是buffer }, response);

node处理编码问题比python还麻烦么?

request.get({ encoding: null, url: ‘…’ }) setEncoding( null ),得到的就是 raw data 了

http://www.cnblogs.com/linka/p/6658055.html

针对Node.js中使用request库请求包含GB2312或GBK编码的网页时出现中文乱码的问题,可以通过引入iconv-litebufferhelper库来解决。以下是具体步骤和代码示例:

解决方案

  1. 安装所需的库

    npm install request iconv-lite bufferhelper
    
  2. 编写代码

    • 使用request库发起HTTP请求。
    • 使用BufferHelper收集响应数据。
    • 使用iconv-lite将缓冲区中的数据解码为正确的字符集(如GBK)。

示例代码

const request = require('request');
const BufferHelper = require('bufferhelper');
const iconv = require('iconv-lite');

function fetchContent(url, callback) {
    const req = request(url, { timeout: 10000, pool: false });
    req.setMaxListeners(50);
    req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36');
    req.setHeader('accept', 'text/html,application/xhtml+xml');

    req.on('error', function (err) {
        console.error(err);
    });

    req.on('response', function (res) {
        const bufferHelper = new BufferHelper();
        res.on('data', function (chunk) {
            bufferHelper.concat(chunk);
        });
        res.on('end', function () {
            const result = iconv.decode(bufferHelper.toBuffer(), 'GBK');
            callback(result);
        });
    });
}

代码解释

  • fetchContent 函数接收一个URL和回调函数作为参数。
  • 使用request发起HTTP请求,并设置超时时间和连接池配置。
  • 设置用户代理和接受类型头部信息以模拟浏览器行为。
  • 监听错误事件来捕获请求过程中的任何错误。
  • 监听响应事件来处理服务器返回的数据。
  • 使用BufferHelper收集所有数据片段并合并到一个大的缓冲区中。
  • 使用iconv-litedecode方法将缓冲区内容解码为GBK格式。
  • 最后调用回调函数传回解码后的字符串。

这样可以确保从服务器接收到的数据能够正确地被解码为GBK格式,从而避免中文乱码问题。

回到顶部