如何解压缩(解压缩)NodeJS 请求的module gzip 响应正文?

IT技术 javascript node.js express zlib
2021-02-12 09:58:04

如何在请求的module响应中解压缩 gzip 压缩的正文?

我在网上尝试了几个例子,但似乎没有一个有效。

request(url, function(err, response, body) {
    if(err) {
        handleError(err)
    } else {
        if(response.headers['content-encoding'] == 'gzip') {    
            // How can I unzip the gzipped string body variable?
            // For instance, this url:
            // http://highsnobiety.com/2012/08/25/norse-projects-fall-2012-lookbook/
            // Throws error:
            // { [Error: incorrect header check] errno: -3, code: 'Z_DATA_ERROR' }
            // Yet, browser displays page fine and debugger shows its gzipped
            // And unzipped by browser fine...
            if(response.headers['content-encoding'] && response.headers['content-encoding'].toLowerCase().indexOf('gzip') > -1) {   
                var body = response.body;                    
                zlib.gunzip(response.body, function(error, data) {
                    if(!error) {
                        response.body = data.toString();
                    } else {
                        console.log('Error unzipping:');
                        console.log(error);
                        response.body = body;
                    }
                });
            }
        }
    }
}
6个回答

我也无法请求工作,所以最终使用 http 代替。

var http = require("http"),
    zlib = require("zlib");

function getGzipped(url, callback) {
    // buffer to store the streamed decompression
    var buffer = [];

    http.get(url, function(res) {
        // pipe the response into the gunzip to decompress
        var gunzip = zlib.createGunzip();            
        res.pipe(gunzip);

        gunzip.on('data', function(data) {
            // decompression chunk ready, add it to the buffer
            buffer.push(data.toString())

        }).on("end", function() {
            // response and decompression complete, join the buffer and return
            callback(null, buffer.join("")); 

        }).on("error", function(e) {
            callback(e);
        })
    }).on('error', function(e) {
        callback(e)
    });
}

getGzipped(url, function(err, data) {
   console.log(data);
});
这是有效的,但通过在请求module上设置几个选项,有一种更好、更简单的方法来做到这一点。请阅读下面我的回答。
2021-03-15 09:58:04
我尝试使用所有请求方法但失败了。这个有效!
2021-03-16 09:58:04
最后!我一直在努力设置标头以接受 gzip 并尝试代理和所有类型的东西,但这确实与 stackoverflow API 一起工作!一件小事:var gunzip = gzip.createGunzip();应该是var gunzip = zlib.createGunzip();
2021-03-23 09:58:04

尝试添加encoding: null到您传递给的选项request,这将避免将下载的正文转换为字符串并将其保存在二进制缓冲区中。

我遇到了同样的问题,这个编码选项对我有用。谢谢 !!
2021-03-21 09:58:04

就像@Iftah 所说的,设置encoding: null.

完整示例(较少的错误处理):

request = require('request');
zlib = require('zlib');

request(url, {encoding: null}, function(err, response, body){
    if(response.headers['content-encoding'] == 'gzip'){
        zlib.gunzip(body, function(err, dezipped) {
            callback(dezipped.toString());
        });
    } else {
        callback(body);
    }
});

实际上请求module处理 gzip 响应。为了告诉请求module解码回调函数中的 body 参数,我们必须在选项中将 'gzip' 设置为 true。让我用一个例子来解释你。

例子:

var opts = {
  uri: 'some uri which return gzip data',
  gzip: true
}

request(opts, function (err, res, body) {
 // now body and res.body both will contain decoded content.
})

注意:您在 'reponse' 事件中获得的数据不会被解码。

这对我有用。希望它也适用于你们。

我们在使用 request module时通常遇到的类似问题是 JSON 解析。让我解释一下。如果您希望请求module自动解析正文并在正文参数中为您提供 JSON 内容。然后你必须在选项中将 'json' 设置为 true。

var opts = {
  uri:'some uri that provides json data', 
  json: true
} 
request(opts, function (err, res, body) {
// body and res.body will contain json content
})

参考:https : //www.npmjs.com/package/request#requestoptions-callback

设置"gzip": true选项的一个警告......服务器响应必须包含一个"Content-Encoding": "gzip"请求module来实际解压缩响应。我一直在处理一个没有正确设置“Content-Encoding”标头的服务器,直到我阅读请求module的源代码我才发现这是必需的。希望此评论能帮助其他人节省时间,在您面临类似情况时试图弄清楚为什么这不起作用。
2021-03-29 09:58:04
这次真是万分感谢!!它有效,我不知道 request-promise 有一个 gzip 标志。
2021-04-11 09:58:04

https://gist.github.com/miguelmota/9946206 所示

截至 2017 年 12 月,请求和请求Promise都开箱即用:

var request = require('request')
  request(
    { method: 'GET'
    , uri: 'http://www.google.com'
    , gzip: true
    }
  , function (error, response, body) {
      // body is the decompressed response body
      console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
      console.log('the decoded data is: ' + body)
    }
  )