Подтвердить что ты не робот

Node.js - простые HTTP-запросы с сжатием gzip/deflate

Я пытаюсь выяснить, как наилучшим образом легко отправлять запросы HTTP/HTTPS и обрабатывать сжатые ответы gzip/deflate вместе с кукисами.

Лучшее, что я нашел, это https://github.com/mikeal/request, который обрабатывает все, кроме сжатия. Есть ли модуль или метод, который будет делать все, что я прошу?

Если нет, могу ли я объединить запрос и zlib каким-то образом? Я попытался объединить zlib и http.ServerRequest, и он потерпел неудачу.

Спасибо!

4b9b3361

Ответ 1

Примечание: с 2019 года в запрос встроена распаковка gzip. Вы по-прежнему можете распаковывать запросы вручную, используя метод ниже.

Вы можете просто совместить request и zlib с потоками.

Вот пример, предполагающий, что у вас есть сервер, слушающий порт 8000:

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

var headers = {
    'Accept-Encoding': 'gzip'
};

request({url:'http://localhost:8000/', 'headers': headers})
    .pipe(zlib.createGunzip()) // unzip
    .pipe(process.stdout); // do whatever you want with the stream

Ответ 2

Для тех, кто сталкивается с этим в последнее время, библиотека запросов теперь поддерживает распаковку gzip. Используйте следующее:

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

Из github readme https://github.com/request/request

gzip - если true, добавьте заголовок Accept-Encoding для запроса сжатого кодировки содержимого с сервера (если они еще не присутствуют) и декодировать поддерживаемые кодировки содержимого в ответе. Примечание. Автоматическое декодирование содержимого ответа выполняется по данным тела, возвращаемым через запрос (как через поток запроса, так и переданный на обратный вызов функция), но не выполняется в потоке ответа (доступный из событие ответа), который является неизмененным http.IncomingMessage объект, который может содержать сжатые данные. См. Пример ниже.

Ответ 3

Вот рабочий пример, который запускает ответ

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

Ответ 5

//functions.js:
var ce=require('cloneextend');
//console.log({aa:'bb',dd:new Date('10/10/2011')});
//console.log(ce.clone({aa:'bb',dd:new Date('10/10/2011')}));
exports.cloneextend=ce;
exports.clone=ce.clone;
exports.extend=ce.extend;
    ////////////request
var request1=require('request');
var Iconv=require('iconv').Iconv;
var iconv_utf8_to_latin = new Iconv('utf-8','iso-8859-1');
var iconv_iso8859_8i_to_utf8 = new Iconv('iso-8859-8','utf-8');
var iconv_utf8_to_iso8859_8i = new Iconv('utf-8','iso-8859-8');
exports.iconv_iso8859_8i_to_utf8=iconv_iso8859_8i_to_utf8;
exports.iconv_utf8_to_iso8859_8i=iconv_utf8_to_iso8859_8i;

var zlib=require('zlib');

function request_unzip(options,cb)
{
 var enc=options.encoding;
 options.encoding=null;
 var r=request1(options)
 .on('response',function(response)
 {
  var bufarr=[];
  var errored=false;
  switch (response.headers['content-encoding'])
  {
     // or, just use zlib.createUnzip() to handle both cases
     case 'gzip':
     case 'deflate':
       if(response.headers['content-encoding']=='gzip')
         var zpipe=zlib.createGunzip();
       else
         var zpipe=zlib.createInflate();

       zpipe
                 .on('data', function(d){bufarr.push(d);})           
                 .on('end', function(){ if(errored) return;errored=true; cb(null,response, enc?Buffer.concat(bufarr).toString(enc):Buffer.concat(bufarr) ); })
                 .on('error', function(err){ if(errored) return;errored=true; cb(err,response,null);});      
       response.pipe(zpipe);
       response
                 .on('error', function(err){ if(errored) return;errored=true; cb(err,response,null);});
       break;
     default:
       response
                 .on('data', function(d){bufarr.push(d);})           
                 .on('end', function(){ if(errored) return;errored=true; cb(null,response, enc?Buffer.concat(bufarr).toString(enc):Buffer.concat(bufarr) ); })
                 .on('error', function(err){ if(errored) return;errored=true; cb(err,response,null);});      
       break;
  }  
 });
 return r; 
}

function request(options,cb)// a request that fixes encoding
{
 if(options.encoding=='iso-8859-8')
 {
  options.encoding='binary';
  return request_unzip(options, function(error,request,data){
   if(data===undefined||data===null)
   {
     data2=null;
     cb(error,request,data2);
   }
   else
   {  
     try{
       cb(error,request,
         iconv_iso8859_8i_to_utf8.convert(iconv_utf8_to_latin.convert(data)).toString('utf8') //conver buffer to string
       );
     }
     catch(e)
     {
      data2=null;
      error=e;
      cb(error,request,data2);
     } 
   }   
  });
 }
 else
  return request_unzip(options,cb);
}
request.__proto__=request1;
exports.request=request;

ie9headers= // no var goes to global
{
 followAllRedirects:true,
 headers:
 {
  "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  "Accept-Language": "he-IL,he;q=0.8,en-US;q=0.6,en;q=0.4",
  "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22",//"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)",              
  "Accept-Charset": "windows-1255,utf-8;q=0.7,*;q=0.3",
  "Accept-Encoding":    "gzip,deflate,sdch"
 }
}

///
example:

f=require('./function.js'); //goes global
function getsomething(cb){
function getit(){
f.request(f.extend({jar:j,url:myurl, headers:{Referer:url}, encoding:'UTF-8' },ie9headers),function(error,request,data)
{
 if(error) setTimeout(getit,1000);
 //console.log("data",data);
 var parsed=myparse(data);
 cb(parsed);
});}
getit();
}

Ответ 6

Внутри исходный код - вы должны установить параметр gzip в самой папке запроса для работы gzip. Не уверен, что это было намеренно или нет, но это текущая реализация. Нет дополнительных заголовков.

var request = require('request');
request.gzip = true;
request({url: 'https://...'},  // use encoding:null for buffer instead of UTF8
    function(error, response, body) { ... }
);