【问题标题】:How to reverse proxy client POST & PUT requests using node-http-proxy如何使用 node-http-proxy 反向代理客户端 POST 和 PUT 请求
【发布时间】:2013-02-27 19:04:39
【问题描述】:

我正在尝试使用 node-http-proxy 作为反向代理,但我似乎无法让 POST 和 PUT 请求工作。文件 server1.js 是反向代理(至少对于带有 url “/forward-this”的请求), server2.js 是接收代理请求的服务器。请解释我做错了什么。

这是 server1.js 的代码:

// File: server1.js
//

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

httpProxy.createServer(function (req, res, proxy) {
    if (req.method == 'POST' || req.method == 'PUT') {
        req.body = '';

        req.addListener('data', function(chunk) {
            req.body += chunk;
        });

        req.addListener('end', function() {
            processRequest(req, res, proxy);
        });
    } else {
        processRequest(req, res, proxy);
    }

}).listen(8080);

function processRequest(req, res, proxy) {

    if (req.url == '/forward-this') {
        console.log(req.method + ": " + req.url + "=> I'm going to forward this.");

        proxy.proxyRequest(req, res, {
            host: 'localhost',
            port: 8855
        });
    } else {
        console.log(req.method + ": " + req.url + "=> I'm handling this.");

        res.writeHead(200, { "Content-Type": "text/plain" });
        res.write("Server #1 responding to " + req.method + ": " + req.url + "\n");
        res.end();
    }
}

这是 server2.js 的代码:

// File: server2.js
// 

var http = require('http');

http.createServer(function (req, res, proxy) {
    if (req.method == 'POST' || req.method == 'PUT') {
        req.body = '';

        req.addListener('data', function(chunk) {
            req.body += chunk;
        });

        req.addListener('end', function() {
            processRequest(req, res);
        });
    } else {
        processRequest(req, res);
    }

}).listen(8855);

function processRequest(req, res) {
    console.log(req.method + ": " + req.url + "=> I'm handling this.");

    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write("Server #2 responding to " + req.method + ': url=' + req.url + '\n');
    res.end();
}

【问题讨论】:

    标签: node.js node-http-proxy


    【解决方案1】:

    http-proxy 依赖于 POST / PUT 请求的 dataend 事件。 server1 收到请求和被代理之间的延迟意味着 http-proxy 完全错过了这些事件。你有两个选项可以让它正常工作 - 你可以buffer the request 或者你可以使用routing proxy 代替。路由代理在这里似乎是最合适的,因为您只需要代理一部分请求。这是修改后的 server1.js:

    // File: server1.js
    //
    
    var http = require('http');
    var httpProxy = require('http-proxy');
    var proxy = new httpProxy.RoutingProxy();
    
    http.createServer(function (req, res) {
        if (req.url == '/forward-this') {
            return proxy.proxyRequest(req, res, {
                host: 'localhost',
                port: 8855
            });
        }
    
        if (req.method == 'POST' || req.method == 'PUT') {
            req.body = '';
    
            req.addListener('data', function(chunk) {
                req.body += chunk;
            });
    
            req.addListener('end', function() {
                processRequest(req, res);
            });
        } else {
            processRequest(req, res);
        }
    
    }).listen(8080);
    
    function processRequest(req, res) {
        console.log(req.method + ": " + req.url + "=> I'm handling this.");
    
        res.writeHead(200, { "Content-Type": "text/plain" });
        res.write("Server #1 responding to " + req.method + ": " + req.url + "\n");
        res.end();
    }
    

    【讨论】:

    • 虽然这是一个旧答案,但要使其正常工作,您应该将 var proxy = new httpProxy.RoutingProxy(); 替换为 var proxy = httpProxy.createProxyServer({});
    【解决方案2】:

    除了@squamos

    How to write a node express app that serves most local files, but reroutes some to another domain?

    var proxy = new httpProxy.RoutingProxy();
    

    “以上代码适用于 http-proxy ~0.10.x。从那时起,库中发生了很多变化。您可以在下面找到新版本的示例(在编写 ~1.0.2 时)”

    var proxy = httpProxy.createProxyServer({});
    

    【讨论】:

      【解决方案3】:

      这是我代理 POST 请求的解决方案。这不是最理想的解决方案,但它有效且易于理解。

      var request = require('request');
      
      var http = require('http'),
          httpProxy = require('http-proxy'),
          proxy = httpProxy.createProxyServer({});
      
      http.createServer(function(req, res) {
          if (req.method == 'POST') {
              request.post('http://localhost:10500/MyPostRoute',
                           {form: {}},
                           function(err, response, body) {
                               if (! err && res.statusCode == 200) {
                                  // Notice I use "res" not "response" for returning response
                                  res.writeHead(200, {'Content-Type': "application/json"});
                                  res.end(body);
                               }
                               else {
                                   res.writeHead(404, {'Content-Type': "application/json"});
                                   res.end(JSON.stringify({'Error': err}));
                               }
                           });
          }
          else  if (req.method == 'GET') {
              proxy.web(req, res, { target: 'http://localhost/9000' }, function(err) {
                  console.log(err) 
              });
          }
      

      端口105009000 是任意的,在我的代码中,我根据我托管的服务动态分配它们。这不处理 PUT 并且它可能效率较低,因为我正在创建另一个响应而不是操纵当前响应。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-15
        • 2013-09-14
        • 2015-11-01
        • 2016-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多