2012-01-16 2 views
33

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

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

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

Спасибо!

+0

Возможный дубликат [Как ungzip (распаковка) тела ответа модуль сжатия оставить заявку на NodeJS в?] (Http://stackoverflow.com/questions/12148948/how-do-i-ungzip-decompress-a -nodejs-requests-module-gzip-response-body) –

ответ

53

Вы можете просто комбинировать 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

+1 должен быть принят ответ – Spoike

+1

Есть ли способ разграничения ответов, которые скремблированы, дефлированы или иным образом сжаты или не сжаты. Поскольку веб-сервер не может возвращать сжатые ответы и не уважать заголовок. – CMCDragonkai

+0

@CMCDragonkai Я отредактировал ответ, чтобы сделать декодирование условным. –

3

Заканчивать примеры на http://nodejs.org/docs/v0.6.0/api/zlib.html#examples

Zlib теперь встроен в узел.

+0

Хм, этих примеров было недостаточно для того, чтобы я мог выяснить, как использовать node.js с require и zlib в API-интерфейсе Stack Exchange v2. – hippietrail

5

Вот рабочий пример, который 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

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

Для тех, кто сталкивается с этим в последнее время, библиотека запросов теперь поддерживает распаковку 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 ридх https://github.com/request/request

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

+0

Это неверно для версии 2.53.0, см. Мой ответ. – Yurik

+0

Работает для меня с 2.56.0 – makc

+0

Я добавил объяснение с страницы github. Пример берется непосредственно из документации и должен работать. Убедитесь, что вы используете третий параметр в обратном вызове (тело), ​​поскольку остальная часть ответа, вероятно, сжата –

1

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

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

Это очень странно - в IDEA опция gzip: true не применяется к self , но при работе без отладки работает также и gzip: true. Может потребоваться дальнейшее расследование. – Yurik

+0

как использовать его в экспресс и проверить, применяется ли gzip или сжатие! –

Смежные вопросы