Javascript 使用EventEmitter覆盖http.request
我使用的模块使用以下功能覆盖节点:Javascript 使用EventEmitter覆盖http.request,javascript,node.js,fakeweb,Javascript,Node.js,Fakeweb,我使用的模块使用以下功能覆盖节点: var old_request = http.request; http.request = function(options, callback){ var rule = match_rule(options); if(rule){ var res = new events.EventEmitter(); res.headers = rule.headers || {'Content-Type': 'text
var old_request = http.request;
http.request = function(options, callback){
var rule = match_rule(options);
if(rule){
var res = new events.EventEmitter();
res.headers = rule.headers || {'Content-Type': 'text/html'};
return {end: function(){
callback(res);
res.emit('data', rule.body || '');
res.emit('end');
}
};
} else {
return old_request.call(http, options, callback);
}
};
我的问题是,我从另一个文件中的以下代码中得到错误:TypeError:Object#没有方法“on”
:
var req = proto.request(options, function (res) { ... });
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
我认为我的问题出现是因为它不再是一个问题,尽管我可能错了。如何成功覆盖http.requesthttp.request而不出现此问题
背景:我正在使用节点版本0.8.2。请求的NPM版本为2.12.0
更新(2013年2月11日):我想提供有关调用http.request的位置的更多信息,以便更具体地了解需要什么以及导致错误的原因。这就是它的名称:
var proto = (options.protocol === 'https:') ? https : http;
var req = proto.request(options, function (res) {
var output = new StringStream();
switch (res.headers['content-encoding']) {
case 'gzip':
res.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
res.pipe(zlib.createInflate()).pipe(output);
break;
default:
// Treat as uncompressed string
res.pipe(output);
break;
}
output.on('end', function() {
if (settings.cookieJar && res.headers['set-cookie']) {
var cookies = res.headers['set-cookie'];
for (var i = 0; i < cookies.length; i++) {
settings.cookieJar.set(cookies[i]);
}
}
if (res.statusCode >= 300 && res.statusCode < 400) {
if (settings.maxRedirects > settings.nRedirects++) {
// Follow redirect
var baseUrl = options.protocol + '//' + ((proxy) ? options.headers['host'] : options.host),
location = url.resolve(baseUrl, res.headers['location']);
request(location, settings);
} else {
var err = new Error('Max redirects reached.');
err.success = false;
settings.complete(err);
}
} else if (res.statusCode >= 400) {
var err = new Error(output.caught);
err.success = false;
err.code = res.statusCode;
settings.complete(err);
} else {
settings.complete(null, output.caught, res);
}
});
});
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
if (data) { req.write(data); }
req.end();
var proto=(options.protocol==“https:”)?https:http;
var req=协议请求(选项、功能(res){
var输出=新的StringStream();
开关(res.headers['content-encoding']){
案例“gzip”:
res.pipe(zlib.createGunzip()).pipe(输出);
打破
“泄气”案例:
res.pipe(zlib.create充气()).pipe(输出);
打破
违约:
//视为未压缩字符串
资源管道(输出);
打破
}
output.on('end',function(){
if(settings.cookieJar&&res.headers['set-cookie'])){
var cookies=res.headers['set-cookie'];
对于(变量i=0;i=300&&res.statusCode<400){
if(settings.maxRedirects>settings.nRedirects++){
//跟随重定向
var baseUrl=options.protocol+'/'+((代理)?options.headers['host']:options.host),
location=url.resolve(baseUrl,res.headers['location']);
请求(位置、设置);
}否则{
var err=新错误('达到最大重定向');
成功=错误;
设置。完成(错误);
}
}否则如果(res.statusCode>=400){
var err=新错误(output.catch);
成功=错误;
err.code=res.statusCode;
设置。完成(错误);
}否则{
设置。完成(null、output.catch、res);
}
});
});
请求开启('error',函数(err){
成功=错误;
设置。完成(错误);
});
如果(数据){req.write(数据);}
请求结束();
编辑
如果您希望请求的行为完全相同,只是应用程序没有实际命中请求的服务器,那么请尝试使用它来拦截您定义的请求并返回您定义的数据
原始答复:
我想你要找的是更像这样的东西:
var old_request = http.request;
http.request = function(options, callback){
var rule = match_rule(options);
if(rule){
var res = new events.EventEmitter(),
req = new events.EventEmitter();
res.headers = rule.headers || {'Content-Type': 'text/html'};
req.end = function(){
if(callback) callback(res);
res.emit('data', rule.body || '');
res.emit('end');
};
return req;
} else {
return old_request.call(http, options, callback);
}
};
if(rule){
块中的返回值不是EventEmitter是,我如何在此处正确返回EventEmitter?取决于您希望发出的内容。您应该调用req.end()
你会得到一个数据
事件,然后是结束
事件。这就是库的工作方式。因为从来没有调用过,你永远不会得到错误。你真的需要在这里解释你的最终目标。嘿,伙计,一旦我做了这个更改,我会得到一个新的错误:TypeError:Object#没有方法“pipe”
由var req=请求(选项,函数(res){res.pipe(output);})那是因为req
通常是一个可写流,而不仅仅是EventEmitter
;正如我之前所说,如果不知道你的最终目标是什么,我就帮不了你,我只是在猜测。告诉我你想要什么,我可以帮你,但这听起来像是你应该在fakeweb上发布的一个问题,如果你正在使用的话。我“我正试图通过创建一个与Node外观相同的伪http.request使Fakeweb工作到Node。这是我唯一的目标。我想也许像您建议的那样进行一些小的黑客操作会让它“嘎嘎”作响”就像以前的http.request duck一样。这可能不会是一些小的攻击。让我再问一次更具体的问题,如果您调用req.pipe()
在fakeweb one上,您希望发生什么?没有真正的请求进行管道传输,那么数据将流向何处?如果您只是返回一个没有目标的可写流,您真的会得到所需的事件吗?这不是我可以在代码段中键入的内容,这是一项巨大的努力。首先,请尝试使用更好的模块,如insteadChad感谢您继续关注。我意识到我没有提供足够的信息,所以我将代码片段粘贴到http.request实际用于提供上下文和帮助的位置。如果这澄清了我需要如何使用http.request,请告诉我。谢谢。