路线在快车中行驶后,为什么不能叫“下一个”?

时间:2019-05-21 20:10:31

标签: node.js express

我有一条简单的路线,像这样:

memory_usage((sum_num, (i,)), 1e-4)

我从快递那里得到// This is just a health check const endpoint = (req, res, next) => { res.json({ status: 'ok', }); next(); }; router.get('/', endpoint); 。即使我没有其他可能的下一个中间件要运行,或者即使我的Error: Can't set headers after they are sent.中间件实际上不执行任何操作并且是一个空函数,也是如此。

我对中间件和next的工作方式缺少什么?

3 个答案:

答案 0 :(得分:0)

我认为您在自己的问题中回答了该问题:已发送答复后,您将无法对其进行任何处理。如果您考虑一下,这是有道理的。如果使用next来以某种方式修改请求,为什么在发送请求后,它仍然像“正在工作”一样“起作用”?

根据Express docs,这是他们在next请求中使用get的方式:

app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})

答案 1 :(得分:0)

如果您需要在该特定端点中执行其他操作,则在发送响应之前,应采取正确的方法。这是快递架构的工作方式。

如果要对每个端点应用相同的逻辑(看起来像,因为要检查req.pathreq.params和/或req.route),则可以使用中间件收听Express的finish事件:

router.use((req, res, next) => {
  res.on('finish', function() {
    // extra logic here after sending response
  });
  next();
});

const endpoint = (req, res, next) => {
  res.json({
    status: 'ok',
  });
};

router.get('/', endpoint);

答案 2 :(得分:0)

可能有几个问题:

您最后有一个404处理程序(我们都这样做),却被忽略了。例如:

app.get('/path', (req, res, next) => {
  res.json({ greet: "Welcome!" })
  next() // <-- calling next middleware
})

// set up a 404 handler at the end
app.use((req, res) => {
  res.status(404).send('Opps! Not Found');
})

这将导致错误Error: Can't set headers after they are sent.,因为您的404处理程序正在发送响应。

您偶然发现了一个未知功能(或者很明显,您的一条路线未按预期运行,可能是设计错误)。考虑以下路线:

app.get('/path/:id', (req, res, next) => {
  res.json({ message: "Welcome!" });
  next() // <-- calling next middleware
})

app.get('/path/test', (req, res, next) => {
  res.json({ message: "Welcome!" });
})

如果您的请求路径为next,则在/path/:id路由中调用/path/test会导致错误(通常建议采用更好的路由实现方式)

了解middlewarenext的简单方法与switch语句的工作方式有关:

function test(x) {
  switch (x) {
    case 'Oranges':
      console.log('Orange juice');
      break;
    case 'Mangoes': // fall through
    case 'Papayas':
      console.log('Pickles');
      break;
    case 'Banana':
      console.log('Milkshake');
      // forgot the break
    case 'Apple':
      console.log('Apple Pie')
      break;
    default:
      console.log('Sorry, no ' + x + '.');
  }
}

test('Banana')

调用next就像fall through语句的switch,也执行下一种情况。

因此,当您在一条路由中呼叫next并且request继续与要发送响应的另一route(非预期匹配)相匹配时,您会发现自己在欺骗错误的表情。