2012-01-16 16 views
33

Sto cercando di capire come sia il modo migliore per inviare facilmente richieste HTTP/HTTPS e gestire gzip/sgonfiare le risposte compresse insieme ai cookie.node.js - semplici richieste http con compressione gzip/deflate

Il migliore che ho trovato era https://github.com/mikeal/request che gestisce tutto eccetto la compressione. Esiste un modulo o un metodo che farà tutto ciò che chiedo?

In caso contrario, è possibile combinare la richiesta e zlib in qualche modo? Ho provato a combinare zlib e http.ServerRequest, e ha fallito miseramente.

Grazie!

+0

Eventuali duplicati di [Come faccio ungzip (decomprimere) il corpo di risposta del modulo gzip di una richiesta NodeJS?] (Http://stackoverflow.com/questions/12148948/how-do-i-ungzip-decompress-a -nodejs-requests-module-gzip-response-body) –

risposta

53

È possibile combinare semplicemente request e zlib con flussi.

Ecco un esempio supponendo che si dispone di un server in ascolto sulla porta 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

+1 deve essere accettato risposta – Spoike

+1

Esiste un modo per differenziare tra risposte che sono compressi con gzip, sgonfiati o altrimenti compressi o non compressi. Perché il server web non può restituire risposte compresse e non rispettare l'intestazione. – CMCDragonkai

+0

@CMCDragonkai Ho modificato la risposta per rendere condizionale la decodifica. –

5

Ecco un esempio di lavoro che gunzippare la risposta

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

codice completo: https://gist.github.com/0xPr0xy/5002984

1
//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(); 
} 
65

Per chiunque si imbatta in questo negli ultimi tempi, la libreria di richieste supporta ora la decompressione gzip immediata. Utilizzare come segue:

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

Dal readme github https://github.com/request/request

gzip - Se è vero, aggiungere un header Accept-Encoding per richiedere compressa codifiche del contenuto dal server (se non è già presente) e decodificare codifiche del contenuto supportate nella risposta. Nota: la decodifica automatica del contenuto della risposta viene eseguita sui dati del corpo restituiti tramite la richiesta (sia attraverso il flusso di richiesta che passata alla funzione callback ) ma non viene eseguita sul flusso di risposta (disponibile da l'evento di risposta) è l'oggetto non modificato http.IncomingMessage che può contenere dati compressi. Vedi l'esempio qui sotto.

+0

Questo non è corretto per la versione 2.53.0, vedere la mia risposta. – Yurik

+0

Funziona per me con 2.56.0 – makc

+0

Ho aggiunto la spiegazione dalla pagina github. L'esempio è preso direttamente dalla documentazione e dovrebbe funzionare. Assicurati di utilizzare il terzo parametro nel callback (corpo) poiché il resto della risposta è probabilmente compresso –

1

Guardando dentro il source code - è necessario impostare la gzip param sulla richiesta lib se stesso per gzip per lavorare. Non sono sicuro se sia stato intenzionale o meno, ma questa è l'implementazione corrente. Non sono necessarie intestazioni aggiuntive.

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

Questo è molto strano - in IDEA, gzip dell'opzione: true non è applicato all'auto , ma quando si esegue senza eseguire il debug, funziona anche {gzip: true}. Potrebbe essere necessario indagare ulteriormente. – Yurik

+0

come usarlo in espresso e controllare se gzip o compressione è applicata o meno! –

Problemi correlati