Connect or Express middleware to modify the response.body

50,088

Solution 1

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

Solution 2

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.

Solution 3

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

Solution 4

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.

Solution 5

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.

Share:
50,088
blsha
Author by

blsha

Updated on November 06, 2020

Comments

  • blsha
    blsha over 2 years

    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.

  • ragulka
    ragulka over 10 years
    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.
  • Christopher Tarquini
    Christopher Tarquini over 9 years
    Make sure you are calling next in your routes, otherwise express won't execute any middleware after that route
  • jmarceli
    jmarceli almost 4 years
    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') > -1
  • Ronald Das
    Ronald Das about 3 years
    Easy to use library!
  • YakovL
    YakovL about 2 years
    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..
  • Evgeny
    Evgeny almost 2 years
    Unfortunately the transform callback of this middleware does not receive the req and res arguments from the middleware chain.
  • sam
    sam over 1 year
    Not working for express 4, there is no such an property or method called body of Response object according to api doc