2013-02-27 118 views
6

我試圖使用node-http-proxy作爲反向代理,但似乎無法使POST和PUT請求正常工作。文件server1.js是反向代理(至少對於具有url「/ forward-this」的請求),server2.js是接收代理請求的服務器。請解釋我做錯了什麼。如何使用node-http-proxy反向代理客戶端POST&PUT請求

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

回答

4

HTTP代理依賴於dataend事件POST/PUT請求。 server1接收請求和代理服務器之間的等待時間意味着http代理完全錯過了這些事件。你有兩個選擇來使這個工作正常 - 你可以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(); 
} 
+0

完美的工作。謝謝! – 2013-02-28 17:01:40

+0

儘管這是一箇舊的答案,但要使其發揮作用,您應該使用'var proxy = httpProxy.createProxyServer({});'var proxy = new httpProxy.RoutingProxy();' ; – Saber 2017-08-18 19:54:13

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,它可能效率較低,因爲我正在創建另一個響應而不是操作當前的響應。

相關問題