我正在使用fakeweb模块,该模块使用以下函数覆盖Node的http.request
:
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 #<Object> has no method 'on'
:
var req = proto.request(options, function (res) { ... });
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
我认为我的问题出现了,因为它不再是EventEmitter
,尽管我可能错了。如何在不解决此问题的情况下成功覆盖http.request
?
背景:我使用的是Node版本 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();
答案 0 :(得分:0)
修改强>
如果您希望请求的行为完全相同,只是没有应用程序实际访问请求的服务器,请尝试使用nock拦截您定义的请求并返回您定义的数据。
原始答案:
我认为你所寻找的是更像这样的东西:
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);
}
};