30

I need to redirect all the POST requests of my node.js server to a remote server.

I tried doing the following:

app.post('^*$', function(req, res) {
  res.redirect('http://remoteserver.com' + req.path);
});

The redirection works but without the POST parameters. What should I modify to keep the POST parameters?

MartinMoizard
  • 6,600
  • 12
  • 45
  • 75

1 Answers1

62

In HTTP 1.1, there is a status code (307) which indicates that the request should be repeated using the same method and post data.

307 Temporary Redirect (since HTTP/1.1) In this occasion, the request should be repeated with another URI, but future requests can still use the original URI. In contrast to 303, the request method should not be changed when reissuing the original request. For instance, a POST request must be repeated using another POST request.

In express.js, the status code is the first parameter:

res.redirect(307, 'http://remoteserver.com' + req.path);

Read more about it on the programmers stackexchange.

Proxying

If that doesn't work, you can also make POST requests on behalf of the user from the server to another server. But note that that it will be your server that will be making the requests, not the user. You will be in essence proxying the request.

var request = require('request'); // npm install request

app.post('^*$', function(req, res) {
    request({ url: 'http://remoteserver.com' + req.path, headers: req.headers, body: req.body }, function(err, remoteResponse, remoteBody) {
        if (err) { return res.status(500).end('Error'); }
        res.writeHead(...); // copy all headers from remoteResponse
        res.end(remoteBody);
    });
});

Normal redirect:

user -> server: GET /
server -> user: Location: http://remote/
user -> remote: GET /
remote -> user: 200 OK

Post "redirect":

user -> server: POST /
server -> remote: POST /
remote -> server: 200 OK
server -> user: 200 OK
Community
  • 1
  • 1
mak
  • 13,267
  • 5
  • 41
  • 47
  • I tried the redirect with the 307 code, unfortunately it doesn't work. Concerning your second method, I also tried it but the function(err, remoteResponse, remoteBody){} callback never gets called :( – MartinMoizard Jul 15 '13 at 11:19
  • 1
    While this is a true the spec tells a 307 should redirect a POST to another POST, it is common implementation not to do it this way. For instance, Apache HttpClient will redirect a POST to a GET even on a code 307: https://issues.apache.org/jira/browse/HTTPCLIENT-860 – blacelle Mar 21 '14 at 22:55
  • 1
    The headers need to be cleaned for the proxy reauest. For instance, one has to remove the host as it has been resolved for the first server: delete req.headers.host; – blacelle Mar 21 '14 at 23:19
  • In my case (Safari browser and Chrome browser), 307 works when there are no query params attached. I presume it could also work with the same query string in Location. If there is a difference POST parameters are not being sent. – siefca Feb 04 '23 at 12:38