node.js – 使用gzip / deflate压缩的简单http请求
我想弄清楚如何轻松发送HTTP / HTTPS请求,并处理gzip /压缩响应与cookies。
我发现最好的是https://github.com/mikeal/request处理除压缩之外的所有内容。 有没有一个模块或方法可以满足我所要求的一切?
如果没有,我可以以某种方式结合请求和zlib吗? 我试图结合zlib和http.ServerRequest,它失败了。
谢谢!
您可以简单地将request
和zlib
与stream组合。
假设您有一个监听端口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
对于近期遇到此问题的人来说,请求库现在支持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 – 如果为true,则添加一个Accept-Encoding标头,以从服务器请求压缩内容编码(如果尚不存在),并解码响应中支持的内容编码。 注意:响应内容的自动解码是通过请求(通过请求stream并传递给callback函数)返回的主体数据执行的,但不是在未修改的http响应stream(可从响应事件中获得)上执行.IncomingMessage对象可能包含压缩数据。 看下面的例子。
这是一个工作的例子,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
查看http://nodejs.org/docs/v0.6.0/api/zlib.html#examples上的示例;
zlib现在被构build到节点中。
//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(); }
查看源代码 – 你必须在请求库本身设置gzip
参数,gzip才能正常工作。 不知道这是否是有意的,但这是目前的实施。 不需要额外的标题。
var request = require('request'); request.gzip = true; request({url: 'https://...'}, // use encoding:null for buffer instead of UTF8 function(error, response, body) { ... } );