【问题标题】:NodeJS Connect Middleware Function SetupNodeJS Connect 中间件功能设置
【发布时间】:2013-09-28 22:36:47
【问题描述】:

我正在尝试了解中间件的工作原理,特别是 NodeJS 的 Connect 模块。我正在浏览这个http://howtonode.org/connect-it 并找到了这个例子:

module.exports = function logItSetup() {

  // Initialize the counter
  var counter = 0;

  return function logItHandle(req, res, next) {
    var writeHead = res.writeHead; // Store the original function

    counter++;

    // Log the incoming request
    console.log("Request " + counter + " " + req.method + " " + req.url);

    // Wrap writeHead to hook into the exit path through the layers.
    res.writeHead = function (code, headers) {
      res.writeHead = writeHead; // Put the original back

      // Log the outgoing response
      console.log("Response " + counter + " " + code + " " + JSON.stringify(headers));

      res.writeHead(code, headers); // Call the original
    };

    // Pass through to the next layer
    next();
  };
};

所以我知道它会记录传入的请求和响应。但是即使有文章中的以下解释,我仍然不明白您需要将 writeHead 替换为替换函数:

“设置函数是设置中间件跨请求使用的变量的好地方。在这种情况下,我们正在初始化记录器的计数器。

在处理程序中,我们使用包装习语来挂钩对 writeHead 的调用。在 JavaScript 中,函数是值,就像其他任何东西一样。因此,包装函数的一个好方法是将对原始实现的引用存储在闭包变量中。将函数替换为新函数,并在新函数的第一行中,将旧函数定义放回原处。然后在替换函数的最后一行调用原来的。这是挂钩现有对象方法的一种简单而有效的方法,因为它们只是按名称查找属性,而不是对实际函数对象的引用。

独立的console.log调用会在每个请求周期的开始被调用,嵌套的console.log会在退出的时候通过嵌套的writeHead函数被调用。”

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    每次有传入请求时,它都会通过堆栈中间件。这些是带有 3 个参数的简单函数 req,res,next 有点像这样:

    function someMiddleware(req,res,next){
      // do stuff with request & response...
    
      // You need to call next to keep going through the stack
      next(); 
    }
    

    在您的示例中,您可以像这样使用模块:

    connect()
    .use(function(req,res,next){
      //some other handler
      // ...
      // Call next
      next();
    })
    .use(logInSetup) //Assuming you named it like this
    

    模块returns 正是堆栈中间件所期望的功能。我是how connects does it... 基本上是一样的想法。

    writeHead 函数存储在一个变量中,因此您可以在每个请求上调用console.log,然后调用实际函数。考虑到writeHead 不会在调用此函数时被调用,而是在从其他地方调用res.writeHead 时。 这是一种(非常聪明的)修改函数而不改变其原始实现的方法。

    一个非常简单的例子:

    //Assume this function is a dependency and cannot be alter
    function sumNums(a,b){
      return a + b;
    }
    
    var sumNums_copy = sumNums;
    
    function sumNums(a,b) {
      console.log('Log and the sum');
      sumNums_copy(a,b);
    };
    
    sumNums_copy(2,2); // sums
    sumNums(2,2); // sums and logs
    

    函数是 javascript 中的第一类对象,这意味着它们可以作为参数传递给其他函数、从函数返回或存储在变量中。

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      • 2019-02-28
      相关资源
      最近更新 更多