http.get和ISO-8859-1编码的响应

时间:2012-01-18 18:32:26

标签: node.js character-encoding

我即将编写一个RSS-feed抓取器并遇到一些字符集问题。

与编码相比,加载和解析Feed非常简单。 我正在使用http.get加载Feed,并且我将每个数据事件放在一起。 后来我用npm-lib feedparser解析整个字符串,它对给定的字符串工作正常。

可悲的是,我习惯于在php中使用像utf8_encode()这样的函数,而我在node.js中错过了它们,所以我很难使用当前没有按照我想要的方式使用Iconv。

没有编码,有几个utf8?-icons用于错误的字符集,用iconv,字符串被解析错误:/

目前我正在单独编码每个字符串:

//var encoding ≈ ISO-8859-1 etc. (Is the right one, checked with docs etc.)
// Shortend version

var iconv = new Iconv(encoding, 'UTF-8');

parser.on('article', function(article){
    var object = {
        title : iconv.convert(article.title).toString('UTF-8'),
        description : iconv.convert(article.summary).toString('UTF-8')
    }
    Articles.push(object);
});

我应该用数据缓冲区开始编码还是稍后用完整的字符串开始编码?

谢谢!

PS:通过解析xml的头部来确定编码

在node.js中进行编码的模块更容易吗?

2 个答案:

答案 0 :(得分:9)

您可能遇到https://groups.google.com/group/nodejs/browse_thread/thread/b2603afa31aada9c上描述的相同问题。

解决方案似乎是在使用Iconv处理缓冲区之前将响应编码设置为二进制。

相关位是

  

设置response.setEncoding('binary')并在调用Iconv.convert()之前将块聚合到缓冲区中。请注意,encoding = binary意味着您的数据回调将接收Buffer对象,而不是字符串。


已更新这是我最初的回复

您确定您收到的Feed已正确编码吗?

我可以看到两个可能的错误:

  1. 使用Latin-1编码的数据发送Feed,但Content-Type表示charset=UTF-8
  2. 使用UTF-8编码的数据发送Feed,但Content-Type标头没有说明任何内容,默认为ASCII。
  3. 您应该使用Wireshark或cURL等实用程序检查Feed的内容和发送的标题。

答案 1 :(得分:1)

我认为问题可能在于将数据传递给feedparser之前存储数据的方式。没有看到你的数据事件处理程序很难说,但我猜你正在做这样的事情:

values = '';
stream.on('data', function(chunk){
  values += chunk;
});

是吗?

问题在于,在这种情况下,chunk是一个缓冲区,通过使用'+'将它们全部附加在一起,你可以隐式地将缓冲区转换为字符串。

进一步研究,你应该在整个Feed中进行iconv转换,然后再通过feedparser运行,因为feedparser可能不知道其他编码。

尝试这样的事情:

var iconv = new Iconv('ISO-8859-1', 'UTF8');
var chunks = [];
var totallength = 0;
stream.on('data', function(chunk) {
  chunks.push(chunk);
  totallength += chunk.length;
});
stream.on('end', function() {
  var results = new Buffer(totallength);
  var pos = 0;
  for (var i = 0; i < chunks.length; i++) {
    chunks[i].copy(results, pos);
    pos += chunks[i].length;
  }
  var converted = iconv.convert(results);
  parser.parseString(converted.toString('utf8'));
});