Connect or Express middleware to modify the response.body [closed]
Asked Answered
D

5

37

I would like to have a middleware function which modifies the response body.

This is for an express server.

Something like:

function modify(req, res, next){
  res.on('send', function(){
    res.body = res.body + "modified"
  });

  next();
}

express.use(modify);

I don't understand what event to listen for. Any help or documentation would be appreciate.

Delgadillo answered 27/3, 2012 at 19:48 Comment(0)
S
27

You don't need to listen to any events. Just make it

function modify(req, res, next){
  res.body = res.body + "modified";

  next();
}

And use it after you use the router. This way after all your routes have executed you can modify the body

Shrub answered 27/3, 2012 at 21:11 Comment(4)
I am trying to use my middleware after the router, but it seems to be not triggered at all. It is only triggered if I use it before app.router. I am using it insite the app.configure block, if that makes any difference.Hodgson
Make sure you are calling next in your routes, otherwise express won't execute any middleware after that routeShrub
what exactly means "after you use the router"? In a simple app with app.get(someRoute, handler)s and app.listen(port, anotherHandler, do I have to app.use(modify) after app.listen? For me both before and after it seems not to work (I added app.use((req, res, next) => { console.log('after response'); next(); }) and don't see anything in console..Nancynandor
Not working for express 4, there is no such an property or method called body of Response object according to api docCelestina
H
21

I believe the OP actually wants to modify the response stream once a middleware has handled the request. Look at the bundled Compress middleware implementation for an example of how this is done. Connect monkey patches the ServerResponse prototype to emit the header event when writeHead is called, but before it is completed.

Hetero answered 27/2, 2013 at 3:52 Comment(0)
A
14

express-mung is designed for this. Instead of events its just more middleware. Your example would look something like

const mung = require('express-mung')

module.exports = mung.json(body => body.modifiedBy = 'me');
Apraxia answered 9/12, 2015 at 6:13 Comment(2)
Easy to use library!Laos
but isn't this only applicable to json responses? What about text/html?Autotomy
M
10

Overwriting the response's write method seemed to work for me with Express 4. This allows modifying the response's body even when it's a stream.

app.use(function (req, res, next) {
  var write = res.write;
  res.write = function (chunk) {
    if (~res.getHeader('Content-Type').indexOf('text/html')) {
      chunk instanceof Buffer && (chunk = chunk.toString());
      chunk = chunk.replace(/(<\/body>)/, "<script>alert('hi')</script>\n\n$1");
      res.setHeader('Content-Length', chunk.length);
    }
    write.apply(this, arguments);
  };
  next();
});

Just make sure to register this middleware before any other middleware that may be modifying the response.

Malversation answered 23/11, 2015 at 22:25 Comment(1)
To simplify your answer a bit instead of ~res.getHeader('Content-Type').indexOf('text/html') you may use res.getHeader('Content-Type').indexOf('text/html') > -1Marthmartha
T
1

There seems to be a module for doing just this called connect-static-transform, check it out:

https://github.com/KenPowers/connect-static-transform

A connect middleware which allows transformation of static files before serving them.

And it comes with examples, like this one.

Thundercloud answered 20/1, 2015 at 21:11 Comment(2)
Unfortunately the transform callback of this middleware does not receive the req and res arguments from the middleware chain.Higherup
I don't think this is an answer to the question, as it doesn't let you modify the response body. It's just for transforming static files.Gravure

© 2022 - 2024 — McMap. All rights reserved.