node中字节流接收问题【转】

549 查看

今天写代码的时候用到iconv-lite库的decode方法,给出了warning。说是deprecated,于是我顺着他的连接看了一下具体的文章,记录如下。
转自Use Buffers when decoding

首先以下是错误的:

var http = require('http'),
    iconv = require('iconv-lite');

http.get("http://website.com/", function(res) {
  var body = '';
  res.on('data', function(chunk) {
    body += chunk;
  });
  res.on('end', function() {
    var decodedBody = iconv.decode(body, 'win1252');
    console.log(decodedBody);
  });
});

在调用iconv.decode这个函数之前,原始数据已经被javascript内部给decode了。

 res.on('data', function(chunkBuffer) {
    body += chunkBuffer.toString('utf8');
  });

也就是说再调用iconv.decode的话实际就是decode了两次,这样会丢失binary原始数据的。如果你使用了res.setEncoding('utf-8')的话也会有一样的效果。
真正正确的办法是用Buffer类型的数组接收数据,然后拼接,最后decode。代码如下:

http.get("http://website.com/", function(res) {
  var chunks = [];
  res.on('data', function(chunk) {
    chunks.push(chunk);
  });
  res.on('end', function() {
    var decodedBody = iconv.decode(Buffer.concat(chunks), 'win1252');
    console.log(decodedBody);
  });
});

// Or, with iconv-lite@0.4 and Node v0.10+, you can use streaming support with `collect` helper
http.get("http://website.com/", function(res) {
  res.pipe(iconv.decodeStream('win1252')).collect(function(err, decodedBody) {
    console.log(decodedBody);
  });
});

最后作者还提到怎么沉默那条waring的方法:

iconv.skipDecodeWarning = true;```