Joe Beuckman
Joe Beuckman

Reputation: 2296

How to Add Headers to node-http-proxy Response

I need to solve CORS on a third party service, so I want to build a proxy to add the header "Access-Control-Allow-Origin: *".

Why is this code is not adding the header?

httpProxy = require('http-proxy');

var URL = 'https://third_party_server...';

httpProxy.createServer({ secure: false, target: URL }, function (req, res, proxy) {

  res.oldWriteHead = res.writeHead;
  res.writeHead = function(statusCode, headers) {
    /* add logic to change headers here */

    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');

    res.oldWriteHead(statusCode, headers);
  }

  proxy.proxyRequest(req, res, { secure: false, target: URL });

}).listen(8000);

Upvotes: 14

Views: 18114

Answers (3)

elhil
elhil

Reputation: 101

For those coming across this in the future, here's an updated answer. Combining Michael Gummelt's comment and Nicholas Mitrousis' answer, any headers set on res will be overridden if the response from upstream in proxyRes has the same header set. So to answer the original question:

proxy.on('proxyRes', function(proxyRes, req, res) {
 proxyRes.headers["access-control-allow-origin"] = "*";
 proxyRes.headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS";
}

Upvotes: 6

Nicholas Mitrousis
Nicholas Mitrousis

Reputation: 11

Even though this question is old, it's the first result from Google and the current answer isn't terribly informative.

The first point of note is that proxyRes does not have a setHeader() method. Additionally, if you try to override a proxyRes header with res.setHeader('Header-to-Override', 'new value'), it won't work (I assume due to headers being copied from proxyRes to res after this event is fired.

It appears we're not the only ones with this issue: https://github.com/http-party/node-http-proxy/issues/1401

Here's my solution for adding an additional cache-control header in my situation:

proxy.on('proxyRes', function(proxyRes, req, res) {
  if (proxyRes.headers['cache-control']) {
    proxyRes.headers['cache-control'] += ', proxy-revalidate'
  } else {
    proxyRes.headers['cache-control'] = 'proxy-revalidate'
  }
})

Upvotes: 1

regilero
regilero

Reputation: 30546

You have the proxyRes event available.

So something like that should work:

proxy.on('proxyRes', function(proxyRes, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
});

Full working example (well, when I say full I do not mean this is a secure-failsafe-real proxy, but it does the job for your question):

var http = require('http'),
    httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
var server = http.createServer(function(req, res) {
    proxy.web(req, res, {
        target: 'https://third_party_server...',
        secure: false,
        ws: false,
        prependPath: false,
        ignorePath: false,
    });
});
console.log("listening on port 8000")
server.listen(8000);

// Listen for the `error` event on `proxy`.
// as we will generate a big bunch of errors
proxy.on('error', function (err, req, res) {
  console.log(err)
  res.writeHead(500, {
    'Content-Type': 'text/plain'
  });
  res.end("Oops");
});

proxy.on('proxyRes', function(proxyRes, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
});

Upvotes: 18

Related Questions