可以在不使用中间件功能的情况下增强 express.js req 和 res 变量吗?

It is possible to enhance the express.js req and res variables without using a middleware function?

我正在使用 express.js 在 restful 服务中工作,我想增强 req 和 res 变量,例如你可以写类似

app.use(function (req, res, next) {
    res.Ok = function (data) {
        res.status(200).send(data);
    };

    res.InternalError = function (err) {
        res.status(500).send(err);
    };
});

以后

router.get('/foo', function (req, res) {
    res.Ok('foo');
})

这将在响应正文中发送 'foo' 并将状态代码设置为 200,并且运行良好。

我的第一个问题是是否可以在没有中间件功能的情况下添加这样的功能,比如在 属性 或 app 变量的原型中?

第二个问题是,如果你在应用层用中间件函数添加很多功能,会不会有性能问题。此函数是按请求附加到请求和响应对象还是在应用程序启动时附加一次?

我知道 Sails 框架已经这样做了,但我想知道他们是否也使用中间件功能。

除了使用中间件,我不知道还有什么其他方法。但在我看来,您可以执行以下操作来实现几乎相同的目标。

// Some Route
router.get('/foo', function(req, res, next) {
 // ...
 if(err) {
   res.status(500);
   return next(err);
 }
 return res.send('ok');
});

// Another route
router.get('/bar', function(req, res, next) {
  // ...
  if(badUserId) {
    res.status(400);
    return next('Invalid userId.');
  }
  req.result = 'hello';
  return next();
});

router.use(function(req, res) {
  // I prefer to send the result in the route but an
  // approach like this could work
  return res.send(req.result);
});

// Error Middleware
router.use(function(err, req, res, next) {
  if(res.statusCode === 500) {
    // Log the error here
    return res.send('Internal server error');
  } else {
    return res.send(err);
  }
});

我继续挖掘,发现请求和响应对象是使用 __proto__ 属性.

快速公开的
var express = require('express'),
app = express();

app.response.__proto__.foo = function (data) {
    this.status(200).send(data);
};

稍后在路由器中

router.get('/foo', function (req, res, next) {
    res.foo('test');
});

这将在您的浏览器中打印测试,因此可以在不使用任何中间件的情况下添加功能。

注意:我确信这种方法有一些缺点(例如,覆盖明确的预定义属性)但是为了测试目的和添加非常简单的功能,我认为在性能方面稍微好一些。