express.js - 如何拦截response.send()/ response.json()

时间:2015-11-16 09:54:58

标签: javascript express

假设我有多个地方可以调用response.send(someData)。现在我想创建一个全局拦截器,在其中捕获所有.send方法并对someData进行一些更改。 express.js有什么办法吗? (钩子,听众,拦截器......)?

6 个答案:

答案 0 :(得分:33)

您可以定义如下的中间件(从此answer获取和修改)

function modifyResponseBody(req, res, next) {
    var oldSend = res.send;

    res.send = function(data){
        // arguments[0] (or `data`) contains the response body
        arguments[0] = "modified : " + arguments[0];
        oldSend.apply(res, arguments);
    }
    next();
}

app.use(modifyResponseBody);

答案 1 :(得分:8)

针对那些在Google上找到的内容,基于最佳答案:

app.use((req, res, next) => {
    let oldSend = res.send
    res.send = function(data) {
        console.log(data) // do something with the data
        res.send = oldSend // set function back to avoid the 'double-send'
        return res.send(data) // just call as normal with data
    }
    next()
})

答案 2 :(得分:5)

是的,这是可能的。有两种方法可以做到这一点,一种是使用提供拦截的库,并能够根据特定条件运行它:     https://www.npmjs.com/package/express-interceptor

另一种选择是创建自己的中间件(用于表达),如下所示:

function modify(req, res, next){
  res.body = "this is the modified/new response";

  next();
}
express.use(modify);

答案 3 :(得分:0)

只是想提供一个拦截 res.json 的实际使用示例。

在编写 express 服务器时,我们可能会根据以下情况在每个响应中发送 statusmessage

app.post('/test', (req, res) => {
    res.json({status: 1, message: "some_error", otherData: "nothing"})
})

但是,如果我不想每次都写状态和消息怎么办?我可以添加新函数来构建模板响应正文,以便在使用 res.json 时发送数据。

const messageMap = {
    0: "success",
    1: "some_error"
}

app.use((req, res, next) => {
    const originJson = res.json
    res.json = (status, jsonData) => {
        const fixedResponse = {
            status,
            message: messageMap[status]
        }
        originJson.call(res, {...jsonData, ...fixedResponse})
    }
    next()
})

然后我只需要使用下面的功能。

app.get("/test", (req, res) => {
    res.json(1, {otherData: 1})
})

您甚至可以使用构建器模式来执行此操作。

app.use((req, res) => {
    res.buildFixedResponse = function (status)  {
        const fixedResponse = {
            status,
            message: messageMap[status]
        }
        res.json = function (jsonData) {
            originJson.call(this, {...jsonData, ...fixedResponse})
        }
        return this
    }
})

然后触发如下功能。

app.get("/test", (req, res) => {
    res.buildFixedResponse(1).json({otherData: 1})
})

答案 4 :(得分:0)

就我而言,我不得不使用带有 typicode/json-server 的中间件,并且能够获得不同的响应对象,而不仅仅是一个简单的 javascript 数组。

虽然 typicode/json-server 响应类似于:

[
 {
   ...
 }
]

应用中间件后:

module.exports = (req, res, next) => {
 const oldSend = res.send;
 res.send = (data) => {
  const oldData = JSON.parse(data);
  // we want to change the response only if a blunt array is sent
  // also, we do this for the old sake of not sending json arrays
  if(Object.prototype.toString.call(oldData) === '[object Array]') {
   data = {
    data: oldData
   };
  }
  res.send = oldSend;
  return res.send(data);
 };
 next();
}

响应如下:

 {
  data: [
   {
    ...
   }
  ]
 }

答案 5 :(得分:-1)

您可以简单地使用NODEJS和Express进行操作,例如您正在调用一个API,并且想要在发送回响应之前发送修改数据。

router.get('/id', (req,res) => {
... //your code here filling DATA

  let testData = {
    "C1": "Data1",
    "C2": "Data2",
    "yourdata": DATA
  };          
  res.send(testData);
});