Javascript 如何解压缩(解压缩)NodeJS 请求的模块 gzip 响应正文?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12148948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I ungzip (decompress) a NodeJS request's module gzip response body?
提问by izk
How do I unzip a gzipped body in a request's module response?
如何在请求的模块响应中解压缩 gzip 压缩的正文?
I have tried several examples around the web but none of them appear to work.
我在网上尝试了几个例子,但似乎没有一个有效。
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;
}
});
}
}
}
}
采纳答案by WearyMonkey
I couldn't get request to work either, so ended up using http instead.
我也无法请求工作,所以最终使用 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);
});
回答by Iftah
try adding encoding: null
to the options you pass to request
, this will avoid converting the downloaded body to a string and keep it in a binary buffer.
尝试添加encoding: null
到您传递给的选项request
,这将避免将下载的正文转换为字符串并将其保存在二进制缓冲区中。
回答by Andrew Homeyer
Like @Iftah said, set encoding: null
.
就像@Iftah 说的,设置encoding: null
.
Full example (less error 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);
}
});
回答by Sai Teja
Actually request module handles the gzip response. In order to tell the request module to decode the body argument in the callback function, We have to set the 'gzip' to true in the options. Let me explain you with an example.
实际上请求模块处理 gzip 响应。为了告诉请求模块解码回调函数中的 body 参数,我们必须在选项中将 'gzip' 设置为 true。让我用一个例子来解释你。
Example:
例子:
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.
})
Note: The data you get on 'reponse' event is not decoded.
注意:您在 'reponse' 事件中获得的数据不会被解码。
This works for me. Hope it works for you guys too.
这对我有用。希望它也适用于你们。
The similar problem usually we ran into while working with request module is with JSON parsing. Let me explain it. If u want request module to automatically parse the body and provide you JSON content in the body argument. Then you have to set 'json' to true in the options.
我们在使用 request 模块时通常遇到的类似问题是 JSON 解析。让我解释一下。如果您希望请求模块自动解析正文并在正文参数中为您提供 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
})
Reference: https://www.npmjs.com/package/request#requestoptions-callback
参考:https: //www.npmjs.com/package/request#requestoptions-callback
回答by Francisco Carriedo Scher
As seen in https://gist.github.com/miguelmota/9946206:
如https://gist.github.com/miguelmota/9946206 所示:
Both request and request-promise handle it out of the box as of Dec 2017:
截至 2017 年 12 月,请求和请求承诺都开箱即用:
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)
}
)
回答by samwize
I have formulated a more complete answerafter trying the different ways to gunzip, and solving errors to do with encoding.
在尝试了不同的 gunzip 方法并解决了与编码有关的错误后,我制定了一个更完整的答案。
Hope this helps you too:
希望这对你也有帮助:
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
}
}
});
回答by Mark Robson
Here is my two cents worth. I had the same problem and found a cool library called concat-stream
:
这是我的两分钱。我遇到了同样的问题,发现了一个很酷的库,名为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());
}));
回答by user764155
Here's a working example (using the request module for node) that gunzips the response
这是一个对响应进行压缩的工作示例(使用节点的请求模块)
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);
}
Full code: https://gist.github.com/0xPr0xy/5002984