NodeJS - 具有路由更改的反向代理

时间:2013-12-23 20:20:17

标签: node.js routing reverse-proxy

我目前正在使用NodeJS / Express作为在端口80上运行在我的VPS上的简单域路由器。我的routes.coffee看起来像这样:

request = require("request")

module.exports = (app) ->

    #404, 503, error
    app.get "/404", (req, res, next) ->
        res.send "404. Sowway. :("

    app.get "/error", (req, res, next) ->
        res.send "STOP SENDING ERRORS! It ain't cool, yo."

    #Domain Redirects
    app.all '/*', (req, res, next) ->
        hostname = req.headers.host.split(":")[0]

        #Website1.com
        if hostname == 'website1.com'
            res.status 301
            res.redirect 'http://facebook.com/website1'

        #Example2.com
        else if hostname == 'example2.com'
            pathToGo = (req.url).replace('www.','').replace('http://example2.com','')
            request('http://localhost:8020'+pathToGo).pipe(res)

        #Other
        else
            res.redirect '/404'

正如您在Example2.com中所看到的,我正在尝试将代理转发到另一个端口上的另一个节点实例。除了一个问题外,整体而言它完美无缺。如果其他节点实例上的路由更改(从example2.com/page1.html重定向到example2.com/post5),则地址栏中的URL不会更改。有人会碰巧有一个很好的解决方法吗?或者更好的反向代理方式?谢谢!

1 个答案:

答案 0 :(得分:2)

要重定向客户端,您应将设置为3xx并发送location标题。

我不熟悉请求模块,但我相信它会在默认情况下遵循重定向。 另一方面,您将代理请求的响应传递给客户端的响应对象,丢弃标头和状态代码。这就是客户没有被重定向的原因。

这是一个使用内置HTTP客户端的简单反向HTTP代理。它是用编写的,但如果您愿意,可以轻松将其翻译为并使用请求模块。

var http = require('http');
var url = require('url');

var server = http.createServer(function (req, res) {
  parsedUrl = url.parse(req.url);

  var headersCopy = {};
  // create a copy of request headers
  for (attr in req.headers) {
    if (!req.headers.hasOwnProperty(attr)) continue;
    headersCopy[attr] = req.headers[attr];
  }

  // set request host header
  if (headersCopy.host) headersCopy.host = 'localhost:8020';

  var options = {
    host: 'localhost:8020',
    method: req.method,
    path: parsedUrl.path,
    headers: headersCopy
  };

  var clientRequest = http.request(options);

  clientRequest.on('response', function (clientResponse) {
    res.statusCode = clientResponse.statusCode;
    for (header in clientResponse.headers) {
      if (!clientResponse.headers.hasOwnProperty(header)) continue;
      res.setHeader(header, clientResponse.headers[header]);
    }
    clientResponse.pipe(res);
  });

  req.pipe(clientRequest);
});

server.listen(80);

// drop root privileges
server.on('listening', function () {
  process.setgid && process.setgid('nobody');
  process.setuid && process.setuid('nobody');
});