Search code examples
httpserverproxymiddlewarenuxt.js

Nuxt: modify a response from a proxied server using NuxtJS server middleware


I'm using NuxtJS server middleware as a proxy pass as described in this article to proxy incoming requests to an internal service in order to avoid cross domain issues.

const httpProxy = require('http-proxy')
const proxy = httpProxy.createProxyServer()
const API_URL = 'https://api.mydomain.com'

export default function(req, res, next) {
  proxy.web(req, res, {
    target: API_URL
  })
}

How can I analyse the response of the proxied server and potentially modify it at this level?


Solution

  • I've found an example in the http-proxy documentation. To modify the response, selfHandleResponse must be set to true. Here is the example in documentation:

    var option = {
      target: target,
      selfHandleResponse : true
    };
    proxy.on('proxyRes', function (proxyRes, req, res) {
        var body = [];
        proxyRes.on('data', function (chunk) {
            body.push(chunk);
        });
        proxyRes.on('end', function () {
            body = Buffer.concat(body).toString();
            console.log("res from proxied server:", body);
            res.end("my response to cli");
        });
    });
    proxy.web(req, res, option);
    

    The code below allowed me to handle the proxied answer if the request matches a certain url and just forward (pipe) it otherwise.

    proxy.once('proxyRes', function(proxyRes, req, res) {
      if (!req.originalUrl.includes('api/endpoint')) {
        res.writeHead(proxyRes.statusCode) // had to reset header, otherwise always replied proxied answer with HTTP 200
        proxyRes.pipe(res)
      } else {
        // modify response
        let body = []
        proxyRes.on('data', function(chunk) {
          body.push(chunk)
        })
        proxyRes.on('end', function() {
          body = Buffer.concat(body).toString()
          console.log('res from proxied server:', body)
          res.end('my response to cli')
        })
      }
    })
    

    Note I add to replace .on() with once() to make it work.