Comment puis-je supprimer ungzip (décomprimer) un module de réponse gzip de module de demande NodeJS?

Comment puis-je décompresser un corps gzipé dans la réponse d'un module de demande?

J'ai essayé plusieurs exemples sur le Web, mais aucun d'eux ne semble fonctionner.

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

Je ne pouvais pas obtenir la demande de travailler non plus, alors j'ai fini par utiliser http à la place.

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

Essayez d'ajouter un encoding: null aux options que vous passez à request , cela évitera de convertir le corps téléchargé en une chaîne et de le conserver dans un tampon binaire.

Comme l'a déclaré @Iftah, définissez le encoding: null .

Exemple complet (moins de gestion des erreurs):

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

En fait, le module de demande gère la réponse gzip. Pour indiquer au module de requête de décoder l'argument du corps dans la fonction de rappel, nous devons définir le «gzip» comme étant vrai dans les options. Permettez-moi de vous expliquer avec un exemple.

Exemple:

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

Remarque: les données que vous obtenez sur l'événement «réponse» ne sont pas décodées.

Cela fonctionne pour moi. J'espère que cela fonctionne aussi pour vous.

Le problème similaire que nous avons rencontré en travaillant avec le module de demande est l'analyse par JSON. Permettez-moi de l'expliquer. Si vous souhaitez que le module de demande analyse automatiquement le corps et vous fournisse le contenu de JSON dans l'argument du corps. Ensuite, vous devez définir 'json' sur true dans les options.

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

Référence: https://www.npmjs.com/package/request#requestoptions-callback

Voici un exemple de travail (en utilisant le module de requête pour le noeud) qui lance la réponse

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

Code complet: https://gist.github.com/0xPr0xy/5002984

J'ai formulé une réponse plus complète après avoir essayé les différentes façons de gunzip et de résoudre les erreurs liées à l'encodage.

J'espère que cela vous aide aussi:

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

Voici mes deux cents. J'ai eu le même problème et j'ai trouvé une bibliothèque cool appelée 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()); })); 

Avec, une alternative de request , vous pouvez simplement:

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

La décompression est traitée automatiquement au besoin.