简体   繁体   English

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

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

Lets say I have multiple places where I call response.send(someData) .假设我有多个地方可以调用response.send(someData) Now I want to create a single global interceptor where I catch all .send methods and make some changes to someData .现在,我想创建一个单一的全球性的拦截,我捕捉所有.send方法和做一些改变someData Is there any way in express.js? express.js 有什么办法吗? (hooks, listeners, interceptors, ...)? (钩子,侦听器,拦截器,...)?

You can define a middleware as below (taken and modified from this 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);

for those finding on google, based off the top answer:对于那些在谷歌上找到的人,基于最佳答案:

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

Yes this is possible.是的,这是可能的。 There are two ways to do this, one is to use a library that provides the interception, with the ability to run it based on a specific condition: https://www.npmjs.com/package/express-interceptor有两种方法可以做到这一点,一种是使用提供拦截的库,并能够根据特定条件运行它: https : //www.npmjs.com/package/express-interceptor

The other option is to just create your own middleware (for express) as follows:另一种选择是创建您自己的中间件(用于 express),如下所示:

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

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

Just want to provide a practical usage example with intercepting res.json .只是想提供一个拦截res.json的实际使用示例。

When we're writing express server, we might send the status and message in every response according to the situation like below.在编写 express 服务器时,我们可能会根据以下情况在每个响应中发送statusmessage

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

But, what if I don't want to write the status and message in every time?但是,如果我不想每次都写状态和消息怎么办? I could add new function to build a template response body to send the data when using res.json .我可以添加新函数来构建模板响应主体,以便在使用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()
})

Then I just need to use below function.然后我只需要使用下面的功能。

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

You can even use builder pattern to do this.您甚至可以使用构建器模式来执行此操作。

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

Then trigger function like below.然后触发如下功能。

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

For my case, I had to use a middleware with typicode/json-server and be able to get a different response object than just a blunt javascript array.就我而言,我必须使用带有typicode/json-server的中间件,并且能够获得不同的响应对象,而不仅仅是一个简单的 javascript 数组。

While the typicode/json-server response was something like:虽然typicode/json-server响应类似于:

[
 {
   ...
 }
]

After applying the middleware:应用中间件后:

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

The response looks as follows:响应如下所示:

 {
  data: [
   {
    ...
   }
  ]
 }

You can simply do it using NODEJS and Express, say you are calling an API and want to send modify the data before sending response back.您可以简单地使用 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