在发送给客户之前劫持响应

时间:2015-04-27 20:26:09

标签: node.js express

我有以下代码用作中间件

module.exports=function(callback) {
    callbacks.push(callback);
    return function(req,res,next) {
        if (!res.hijacked) {
            res.hijacked=true;
        } else {
            return next();
        }
        var send=res.send;
        res.send=function(data) {
            var body=data instanceof Buffer ? data.toString() : data;
            var requests=[];
            requests.push(function(next) {
                 callbacks[0](req,res)(body,doneWrapper(body,next));
            });
            for (var i=1;i<callbacks.length;i++) {
                var hijackCallback=callbacks[i];
                requests.push(function(result,next) {
                    hijackCallback(req,res)(result,doneWrapper(result,next));
                });
            }
            var that=this;
            async.waterfall(requests,function(err,result) {
                send.call(that,result);
                requests=null;
                body=null;
                that=null;
            });
        };
        next();
    };
};

使用示例如下:

module.exports=function() {
    return hijack(function() {
        return function(result,done) {
            var json={};
            try {
                json=JSON.parse(result);
            } catch(e) {
                return done();
            }
            if (!_.isArray(json)) {
                return done();
            }
            var sorted=_(json).sortBy(function(item) {
                if (_.isObject(item.information)) {
                    return item.information.rangeIndex1 || 999;
                } else {
                    return 1001;
                }
            });
            done(sorted);
        }
    });
};

最初作为路线中的中间件工作得很好。

但是,当我尝试将其设为app.use(hijackMiddleware())时。出了点问题,我收到了Can't set headers after they are sent错误。

但在路由中用作中间件时没有问题。

1 个答案:

答案 0 :(得分:0)

您考虑过使用express-interceptor吗? use真的很容易:

var express     = require('express');
var cheerio     = require('cheerio');
var interceptor = require('express-interceptor');

var app = express();

var finalParagraphInterceptor = interceptor(function(req, res){
  return {
    // Only HTML responses will be intercepted
    isInterceptable: function(){
      return /text\/html/.test(res.get('Content-Type'));
    },
    // Appends a paragraph at the end of the response body
    intercept: function(body, send) {
      var $document = cheerio.load(body);
      $document('body').append('<p>From interceptor!</p>');

      send($document.html());
    }
  };
})

// Add the interceptor middleware
app.use(finalParagraphInterceptor);

app.use(express.static(__dirname + '/public/'));

app.listen(3000);