Express中的全局请求/响应拦截器

时间:2020-04-23 13:03:04

标签: node.js express

我了解快速中间件。它们就像是请求之间的隧道。

req -> t1 -> t2 -> t3 -> res

所有中间件都使用三个参数req, res, nextnext()是将执行传递到下一个隧道的原因。
错误中间件有点不同,因为它们接受四个参数err, req, res, next

因此,如果在任何隧道中发生错误,它将跳过其余部分,并将句柄传递到下一个error middleware

我需要使用中间件制作一个全局拦截器。

app.js

const express = require('express');

const app = express();

//here I can create a middleware for intercepting the request - which is fine
app.use('*', async function(req, res, next) {
  // access req.body here
  next();
});

// route handlers
app.get('/', async function(req, res) {
  // do stuff
  return res.status(200).send({..});
});

// error handler
app.use(async function(err, req, res) {
  // log error
  return res.status(500).send({...});
});

如您所见,我没有将next传递给路由处理程序,如果路由处理程序中发生任何错误,则库会将其传递给下一个错误处理程序本身。

这是我尝试过的,但是出错了。

// route handlers
app.get('/', async function(req, res, next) {
  // do stuff
  res.status(200).send({..});
  next();
});

// error handler
app.use(async function(err, req, res) {
 if(!error)
     //modify res.body
  // log error
  return res.status(500).send({...});
});

错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置

我知道如果尝试再次发送响应,则会发生此错误。

如何在发送响应正文之前对其进行访问并进行修改?

1 个答案:

答案 0 :(得分:0)

我认为,这里唯一的选择不是发送处理程序本身的响应,而是将其传递给另一个中间件。

// route handlers
app.get('/', async function(req, res, next) {
  // do stuff
const locals = {
  status: 200,
   data: data,
   message: message,
}
  res.locals = locals;
  next();
});

// modify locals in  another middleware
app.use( async function(req, res) {
 // access and modify res.locals
return res.status(res.locals.status).send({ 
    message: res.locals.message,
    data: res.locals.data, 
});

任何人都有更好的选择,请提出建议。