Reputation: 3227
I need to modify the response data a module sends to the client, as the module uses res.send
i can't seem to figure out a way for me to modify the data before it's carried out to the client.
Is there any kind of middleware/event that I can use to catch the res.send
and modify the data before its executed?
I am aware that router.use
exists but it's called before the router.post
function and not before the res.send
is sent to the client. So I need some kind of middleware which is called after the router.post
function is done but before anything is sent to the client.
Upvotes: 20
Views: 27686
Reputation: 92925
It can be done by overriding res.send
We override the res.send
function to capture the response body in our API analytics tool as follows
// It will monkey patch the res.send.
// The patch intercepts the send invocation, executes is logic such as atatus.setResponseBody
// then restores the original send function and invokes that to finalize the req/res chain
const resSendInterceptor = (res, send) => (content) => {
// Set response body in Atatus Analytics
// Atatus is our API analytics tool
atatus.setResponseBody(content || '');
// TODO: You can modify your response body as you wish.
// Invoke the original send function.
res.send = send;
send.apply(this, arguments);
};
// Express Middleware
app.use((req, res, next) => {
// Overrides res.send
res.send = resSendInterceptor(res, res.send);
return next();
});
Upvotes: 0
Reputation: 524
One more solution from here:
expressApp.use(function (req, res, next) { req.on("end", function () { console.log('on request end'); }); next(); });
Important Note: To work, this needs to be placed before body parser since it recreates the response object. see this answer
Upvotes: 6
Reputation: 30430
Well you can override the send function:
app.use(function (req, res) {
var send = res.send;
res.send = function (body) { // It might be a little tricky here, because send supports a variety of arguments, and you have to make sure you support all of them!
// Do something with the body...
send.call(this, body);
};
});
If you want to support more than just calling send
(like calling end
method), then you have to override more functions...
You can check connect-livereload on how it adds a script to any html output.
Upvotes: 37
Reputation: 14824
Your lack of code makes it really hard to answer your question, but you could use something like
Express 4.0:
router.use('/path', function (req, res) {
// Modify req
});
.use
on a route will parse that before continuing on to the actual route so if somebody submitted a form or something, it will hit the .use
before it goes to the .post
or .get
Or you can do
Express 4.0:
app.use(function (req, res) {
// Modify Req
if (req.body.hasOwnProperty('some_form_name')) {
// Do Somthing
}
});
Which is the same thing, but it will be called before every request for every route.
Not sure if this answers your question but I think this might be what you're looking for?
Upvotes: -7