20

I'm trying to do something like this:

// Setup prox to handle blog requests
httpProxy.createServer({
    hostnameOnly: true,
    router: {
        'http://localhost': '8080',
        'http://localhost/blog': '2368' 
    }
}).listen(8000);

Previously I was using this:

http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

Basically, I want to still use express... but, when people go to http://localhost/blog get taken to the blog but still be served over port 8080 (which will eventually be port 80)

So I switched it to this and it worked better. The problem is that express takes over the routing (from what I can tell)

var options = {
    // pathnameOnly: true,
    router: {
        'localhost': 'localhost:8080',
        'localhost/blog': 'localhost:2368'
    }
}

// Setup prox to handle blog requests
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(9000);

require('./app/server/router')(app);

http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});
BRogers
  • 3,534
  • 4
  • 23
  • 32
  • 1
    When they go to `/blog` I want it to run my Ghost app that hosts my blog... otherwise, run my normal site. – BRogers Dec 06 '13 at 19:22
  • Struggling in similar kind of issue http://stackoverflow.com/questions/20323332/node-calling-rest-web-services-behind-a-corporate-proxy can you suggest me if you have any solution –  Jan 03 '14 at 06:37

4 Answers4

44

Using http-proxy 1.0 with express:

var httpProxy = require('http-proxy');

var apiProxy = httpProxy.createProxyServer();

app.get("/api/*", function(req, res){ 
  apiProxy.web(req, res, { target: 'http://google.com:80' });
});
rob
  • 17,995
  • 12
  • 69
  • 94
Chandler
  • 1,019
  • 14
  • 23
  • 1
    Hello Chandler, this seems to work when no cookies are involved. Do you know how can I make the sessions work? Thanks in advance. – Lucas Jul 27 '14 at 23:05
  • 3
    How can this be generalized to other http verbs such as post\put\delete? – Jonathan Livni Oct 01 '14 at 11:14
  • @Lucas: As of my knowledge, proxies won't work with cookies. Cookies are not sent to the same origin. unless you rewrite the cookie domain/paths too. I suggest you to try out token based approach. JWT – Sambhav Sharma Nov 12 '14 at 10:53
  • 1
    hi, @Chandler. In your answer, the request would be proxied to http://google.com:80/api/*, is it possible to proxy to a different path on the target server? e.g http://google.com/some_diffrent_service/xxx/yyy. – yuan Dec 22 '14 at 07:56
  • 1
    Possible to just add http_proxy as middleware to express? – lostintranslation Jul 20 '16 at 20:28
9

A very straightforward solution which works seamlessly, and with cookies/authentication as well, using express-http-proxy:

var proxy = require('express-http-proxy');

var blogProxy = proxy('localhost/blog:2368', {
    forwardPath: function (req, res) {
        return require('url').parse(req.url).path;
    }
});

And then simply:

app.use("/blog/*", blogProxy);

I know I'm late to join this party, but I hope this helps someone.

Selfish
  • 6,023
  • 4
  • 44
  • 63
  • When I use proxy with a port (in my case, 5000), and have the app running on port 8050, the proxy still proxies out on port 8050. My code looks like this proxy('core-api:5000', { /* calculate forward path */ }). Did you test the above code, and what port is node hosting on? – Lo-Tan Oct 15 '15 at 16:38
  • @Lo-Tan - Yes, this is working code from a personal server of mine. Note you don't have the `localhost/` prefix showing in the answer. My main express app is listening on port 80. – Selfish Oct 15 '15 at 19:13
  • For some reason I was thinking the proxy URL should show up in chrome developer tools. Doh >< I had another issue instead (bad url path after the host) It works fine :) Thanks! – Lo-Tan Oct 15 '15 at 20:50
  • @Lo-Tan - Happy to help. :) – Selfish Oct 16 '15 at 05:02
  • Error: getaddrinfo ENOTFOUND www.google.co.in www.google.co.in:80 at errnoException (dns.js:26:10) at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:77:26) Getting the above mentioned error. Any idea? – Sasivarnan Jan 01 '16 at 10:03
  • @NitaiJ.Perez Yup. `www.google.com`, `http://www.google.com` and `https://www.google.com` yields the same – Sasivarnan Jan 03 '16 at 05:23
  • I assume this is Google, not trusting your proxy. Which does make sense. Why would you proxy Google? – Selfish Jan 03 '16 at 10:23
  • @NitaiJ.Perez Not Google exactly. Just used google to check this. – Sasivarnan Apr 13 '16 at 12:23
  • This may work well for non-https requests. However, there's no options for configuring secure certs/keys. If you need https, then I'd suggest using http-proxy. – Timothy Perez Apr 19 '16 at 13:51
4

I got this working.

  • Install Ghost and make sure it's working property (default port is 2368)
  • Create your node web app using express (listen on port 80) - nothing special here
  • Install node-http-proxy npm install http-proxy in your web app
  • Create wildcard route for /blog* that proxies requests to Ghost service

    var httpProxy = require('http-proxy');
    
    var proxy = new httpProxy.RoutingProxy();
    app.get('/blog*', function (req, res, next) {
      proxy.proxyRequest(req, res ,{
        host: 'moserlap.splitvr.com',
        port: 2368  
      });
    });
    
  • Update the Ghost config to use a sub directory (only supported in 0.4.0+)

    config = {
      // ### Development **(default)**
      development: {
      // The url to use when providing links to the site, E.g. in RSS and email.
      url: 'http://127.0.0.1/blog',
    ...
    
  • You should now be able to hit http://yoursite.com/blog and all routes work.

  • 3
    This answer doesn't work with http-proxy 1.0, httpProxy.RoutingProxy is no longer a method. see my answer for an update – Chandler Mar 07 '14 at 07:31
2

I have used simple solution to proxified my GET/POST requests.

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

app.post("/api/*", function(req, res) {
  apiProxy.web(req, res, { target: 'http://localhost:5000'})
});
app.get("/api/*", function(req, res) {
  apiProxy.web(req, res, { target: 'http://localhost:5000'})
});

another easier way to handle all type of requests is:

app.all("/api/*", function(req, res) {
  apiProxy.web(req, res, { target: 'http://localhost:5000'})
});

NOTE: above functions must be before bodyparser.

Saqy G
  • 746
  • 1
  • 6
  • 18