如何解压(解压缩)一个NodeJS请求的模块gzip响应正文?

如何在请求的模块响应中解压缩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; } }); } } } } 

我也无法得到要求工作,所以最终使用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); }); 

尝试添加encoding: null传递给request的选项,这将避免将下载的主体转换为string,并将其保存在二进制缓冲区中。

像@Iftah说的那样,设置encoding: null

完整的例子(lesserror handling):

 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); } }); 

其实请求模块处理gzip响应。 为了告诉请求模块解码callback函数中的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. }) 

注意:您在“响应”事件中获得的数据不会被解码。

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

通常我们在处理请求模块时遇到的类似问题是使用JSONparsing。 让我解释一下。 如果你想请求模块自动分析正文,并在body参数中提供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

下面是一个工作示例(使用节点的请求模块),对响应进行gunzips

 function gunzipJSON(response){ var gunzip = zlib.createGunzip(); var json = ""; gunzip.on('data', function(data){ json += data.toString(); }); gunzip.on('end', function(){ parseJSON(json); }); response.pipe(gunzip); } 

完整代码: https : //gist.github.com/0xPr0xy/5002984

我尝试了不同的方法来解决gunzip问题,并解决了与编码有关的错误,我提出了一个更完整的答案 。

希望这也能帮助你:

 var request = require('request'); var zlib = require('zlib'); var options = { url: 'http://some.endpoint.com/api/', headers: { 'X-some-headers' : 'Some headers', 'Accept-Encoding' : 'gzip, deflate', }, encoding: null }; request.get(options, function (error, response, body) { if (!error && response.statusCode == 200) { // If response is gzip, unzip first var encoding = response.headers['content-encoding'] if (encoding && encoding.indexOf('gzip') >= 0) { zlib.gunzip(body, function(err, dezipped) { var json_string = dezipped.toString('utf-8'); var json = JSON.parse(json_string); // Process the json.. }); } else { // Response is not gzipped } } }); 

这是我的两分钱的价值。 我遇到了同样的问题,发现一个名为concat-stream的很酷的库:

 let request = require('request'); const zlib = require('zlib'); const concat = require('concat-stream'); request(url) .pipe(zlib.createGunzip()) .pipe(concat(stringBuffer => { console.log(stringBuffer.toString()); })); 

有了一个request ,你可以简单地做:

 got(url).then(response => { console.log(response.body); }); 

需要时解压缩将自动处理。