Как делают меня ungzip (распаковка) модуль запроса NodeJS gzip орган по ответу?

Как я разархивировал gzipped тело в ответе модуля запроса?

Я попробовал несколько примеров вокруг сети, но ни один из них, кажется, не работает.

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;
                    }
                });
            }
        }
    }
}
62
задан 27 November 2015 в 09:39

9 ответов

Я не мог заставить запрос работать также, поэтому законченный использовать 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);
});
53
ответ дан 31 October 2019 в 13:28

Как сказанный @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);
    }
});
27
ответ дан 31 October 2019 в 13:28

На самом деле модуль запроса обрабатывает gzip ответ. Чтобы сказать модулю запроса декодировать аргумент тела в функции обратного вызова, Мы должны установить 'gzip' на истинный в опциях. Позвольте мне объяснить Вас с примером.

Пример:

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' событие, не декодируются.

Это работает на меня. Надеюсь, что это работает на Вас парни также.

подобная проблема обычно мы сталкивались, в то время как работа с модулем запроса с парсингом JSON. Позвольте мне объяснить это. Если Вы хотите, чтобы модуль запроса автоматически проанализировал тело и предоставил Вам содержание JSON в аргументе тела. Затем необходимо установить 'json' на истинный в опциях.

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

26
ответ дан 31 October 2019 в 13:28

Как замечено в https://gist.github.com/miguelmota/9946206:

И запрос и обещание запроса обрабатывают его из поля по состоянию на декабрь 2017:

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)
    }
  )
6
ответ дан 31 October 2019 в 13:28

Я сформулировал больше полный ответ после попытки различных путей к gunzip и решения ошибок сделать с кодированием.

Hope это помогает Вам также:

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

});
4
ответ дан 31 October 2019 в 13:28

Вот моя ценность за два цента. Я имел ту же проблему и нашел классную библиотеку названной 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());
  }));
3
ответ дан 31 October 2019 в 13:28

С got , request альтернатива, можно просто сделать:

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

Распаковка обрабатывается автоволшебно при необходимости.

1
ответ дан 31 October 2019 в 13:28

попытайтесь добавить encoding: null к опциям, которые Вы передаете request, это постарается не преобразовывать загруженное тело в строку и сохранит его в двоичном буфере.

34
ответ дан 31 October 2019 в 13:28

Вот рабочий пример (использующий модуль запроса для узла) что 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

3
ответ дан 31 October 2019 в 13:28

Другие вопросы по тегам:

Похожие вопросы: