繁体   English   中英

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

[英]express.js - how to intercept response.send() / response.json()

假设我有多个地方可以调用response.send(someData) 现在,我想创建一个单一的全球性的拦截,我捕捉所有.send方法和做一些改变someData express.js 有什么办法吗? (钩子,侦听器,拦截器,...)?

您可以定义一个中间件如下(从这个答案中获取和修改)

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);

对于那些在谷歌上找到的人,基于最佳答案:

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()
})

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

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

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

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

只是想提供一个拦截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})
})

就我而言,我必须使用带有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: [
   {
    ...
   }
  ]
 }

您可以简单地使用 NODEJS 和 Express 来完成,假设您正在调用 API 并希望在发送响应之前发送修改数据。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM