javascript - 用 EventEmitter 覆盖 http.request

标签 javascript node.js fakeweb

我正在使用 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();

最佳答案

编辑

如果您希望请求完全相同,只是应用程序没有实际访问请求的服务器,请尝试使用 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);
    }
};

关于javascript - 用 EventEmitter 覆盖 http.request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14784220/

相关文章:

javascript - 更新跨项目导出的对象

node.js - Grunt 突然停止工作

javascript - users.get(principalID) 的 azure-graph 权限

node.js - Telegraf 守护程序未从使用 Dokku 部署的应用程序接收指标

ruby - 如何编写测试以指定 ruby​​ 中的 http 请求格式?

ruby-on-rails - RSpec::Core::ExampleGroup::Nested_2 中未定义的方法 `it'

javascript - Node-webkit 与 orm

javascript - AngularJS表达式中的变量

javascript - NodeJS : Getting Input