14

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);
1
  • 4
    try using the module cors, npm install cors Commented Jan 8, 2016 at 19:49

3 Answers 3

18

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');
});
Sign up to request clarification or add additional context in comments.

4 Comments

So, you've to set the headers in res (you can either set in proxyRes event or proxyReq event). Not in proxyRes or proxyReq parameters on those events.
Note that this doesn't seem to work if the target has already set Access-Control-Allow-Origin, since your custom value will be overwritten when the proxy writes to res.
It gives me the error "has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
Well, this answer is from 2013, things may have changed a bit. But I think your main problem here is that you do not have a 200 Ok response to your OPTION http query It does not have HTTP ok status and that's another problem.
6

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";
}

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.