如何使用request或http模块将gzip页面读入字符串

use*_*085 13 http zlib request node.js

我发现js中的请求模块无法正确处理gzip或inflate格式的http响应.

例如:

request({url:'some url'}, function (error, response, body) {
   //if the content-encoding is gzip, the body param here contains binaries other than readable string. And even worse after you convert the body to buffer, u even can not gunzip it.
}
Run Code Online (Sandbox Code Playgroud)

所以我想在官方文档中使用示例代码.

var request = http.get({ host: 'izs.me',
                         path: '/',
                         port: 80,
                         headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', function(response) {
  var output = fs.createWriteStream('izs.me_index.html');

  switch (response.headers['content-encoding']) {
    // or, just use zlib.createUnzip() to handle both cases
    case 'gzip':
      response.pipe(zlib.createGunzip()).pipe(output);
      break;
    case 'deflate':
      response.pipe(zlib.createInflate()).pipe(output);
      break;
    default:
      response.pipe(output);
      break;
  }
});
Run Code Online (Sandbox Code Playgroud)

问题是代码是将网页写入文件,我希望它可以将页面写入字符串,以便我可以处理页面.我找不到像'StringStream'这样的类.

如果有人对此有任何想法,那就太好了.

Tee*_*nen 18

将响应传递给gzip流并像使用原始响应对象一样使用它.

var req = http.request(options, function(res) {
    var body = "";

    res.on('error', function(err) {
       next(err);
    });

    var output;
    if( res.headers['content-encoding'] == 'gzip' ) {
      var gzip = zlib.createGunzip();
      res.pipe(gzip);
      output = gzip;
    } else {
      output = res;
    }

    output.on('data', function (data) {
       data = data.toString('utf-8');
       body += data;
    });

    output.on('end', function() {
        return next(false, body);
    });
 });

req.on('error', function(err) {
   next(err);
})
Run Code Online (Sandbox Code Playgroud)

  • 使用该代码来支持**deflate**:if(res.headers ['content-encoding'] =='deflate'){output = zlib.createInflate(); res.pipe(输出); }` (2认同)

Daw*_*wid 6

简化示例:

var https = require('https');
var gunzip = require('zlib').createGunzip();

var options = {
    host: 'api.stackexchange.com',
    path: '/2.1/info?site=stackoverflow'
};

https.get(options, function(res) {
  var body = '';

  res.pipe(gunzip);

  gunzip.on('data', function (data) {
      body += data;
  });

  gunzip.on('end', function() {
      console.log(JSON.parse(body));
  });
});
Run Code Online (Sandbox Code Playgroud)