如何反向代理客户端POST&使用node-http-proxy的PUT请求

时间:2013-02-27 19:04:40

标签: node.js node-http-proxy

我试图将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();
}

3 个答案:

答案 0 :(得分:5)

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();
}

答案 1 :(得分: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({});

答案 2 :(得分:1)

这是我的代理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,它可能效率较低,因为我正在创建另一个响应,而不是操纵当前的响应。