4
votes

How do I proxy requests with query string parameters in nodejs, I am currently using express and http-proxy?

I have a nodejs application using express and the http-proxy module to proxy HTTP GET requests from certain paths on my end to a third party API running on the same server but a different port (and hence suffering from the same origin issue, requiring the proxy). This works fine until I want to call a REST function on the backend API with query string parameters i.e. "?name=value". I then get a 404.

var express = require('express');
var app = express();
var proxy = require('http-proxy');
var apiProxy = proxy.createProxyServer();

app.use("/backend", function(req,res){
    apiProxy.web(req,res, {target: 'http://'+ myip + ':' + backendPort + '/RestApi?' + name + '=' + value});
});

Chrome's console shows:

"GET http://localhost:8080/backend 404 (Not Found)"

Notes: I use other things in express later, but not before the proxying lines and I go from more specific to more general when routing paths. The backend can be accessed directly in a browser using the same protocol://url:port/path?name=value without issue.

4
I'm having the same issue. Did you find a solution?Laoujin
@Laoujin No solution yet. I worked around the issue instead of fixing it. I should really go look at the http-proxy code and find the issue, I'm pretty sure it's supposed to support this use case.Encaitar

4 Answers

7
votes

I got this working by changing the req.url to contain the querystring params and pass the hostname only to the apiProxy.web target parameter:

app.use('/*', function(req, res) {
    var proxiedUrl = req.baseUrl;
    var url = require('url');
    var url_parts = url.parse(req.url, true);
      if (url_parts.search !== null) {
        proxiedUrl += url_parts.search;
    }

    req.url = proxiedUrl;

    apiProxy.web(req, res, {
      target: app.host
    });
});
4
votes

2017 Update

To proxy request parameters and query strings pass the Express v4 originalUrl property:

app.use('/api', function(req, res) {

  req.url = req.originalUrl    //<-- Just this!

  apiProxy.web(req, res, {
    target: {
      host: 'localhost',
      port: 8080
    }
  })
0
votes

Use the following to append the query string parameters to the req.url

app.use('/api', function(req, res) {

  var qs = require("qs"); 

  req.url = qs.stringify(req.query, {
    addQueryPrefix: true
  });

  apiProxy.web(req, res, {
    target: {
      host: 'localhost',
      port: 8080
    }
 })
0
votes

This was such a time waster for me - (killing process and restart)

then I started using kill-port and I never get the error any more

const express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    kill = require('kill-port'),
    port = 5000;

const main = (req,res,app) => {
    // now you can start listening
    app.listen(port, function () {
        console.log('Server is running on port: ' + port);
    });
    // do stuff....
}

app.get("/myrest", (req, res) => {
    kill(port, 'tcp')
    .then(main(req,res,app))
    .catch(console.log);
});