我想为某些我不是管理员的XYZ服务器设置代理。 然后我想对请求和响应头进行一些分析,然后对请求和响应主体进行分析。 所以我使用的是http-proxy https://github.com/nodejitsu/node-http-proxy
这就是我在做的事情:
var proxy = httpProxy.createProxyServer();
connect.createServer(
connect.bodyParser(),
require('connect-restreamer')(),
function (req, res) {
proxy.web(req, res, { target : 'XYZserver' });
}
).listen(config.listenPort);
Upto GET请求一切正常,但每当有一些请求如POST,PATCH,PUT等请求时,我都会收到错误:
Error: socket hang up
at createHangUpError (http.js:1472:15)
at Socket.socketCloseListener (http.js:1522:23)
at Socket.EventEmitter.emit (events.js:95:17)
at TCP.close (net.js:466:12)
我谷歌很多,但发现没有任何线索的错误。 我使用'proxy.web'的'ws:true'选项启用套接字代理,但仍然是相同的错误。
答案 0 :(得分:18)
我有一个类似的问题,并通过将我的代理代码移到其他节点中间件之上来解决它。
e.g。这样:
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
app.use("/someroute", function(req, res) {
apiProxy.web(req, res, { target: 'http://someurl.com'})
});
app.use(someMiddleware);
不是这个:
app.use(someMiddleware);
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
app.use("/someroute", function(req, res) {
proxy.web(req, res, { target: 'http://someurl.com'})
});
我的具体问题是将BodyParser中间件置于代理上方。我还没有做太多挖掘,但它必须以某种方式修改了请求,当请求最终到达时,它会破坏代理库。
答案 1 :(得分:9)
为了完整起见,模块body-parser
和http-proxy
之间确实存在集成问题,如this主题中所述。
如果你不能改变中间件的顺序;在代理请求之前,您可以重新注释已解析的正文。
// restream parsed body before proxying
proxy.on('proxyReq', function(proxyReq, req, res, options) {
if (req.body) {
let bodyData = JSON.stringify(req.body);
// incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
proxyReq.setHeader('Content-Type','application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
// stream the content
proxyReq.write(bodyData);
}
}
我在这个问题上已经失去了2天。希望它有所帮助!
答案 2 :(得分:5)
需要捕获代理的错误:
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({ target: argv.proxy_url })
proxy.on('error', function(err, req, res) {
res.end();
})
答案 3 :(得分:3)
似乎http-proxy
与body-parser
中间件不兼容。
您可能希望在http-proxy
之前移动body-parser
中间件或停止使用body-parser
。
另见: Socket hangup while posting request to Node-http-proxy Node.js
答案 4 :(得分:3)
在浪费了一天多的时间并在nodejitsu/node-http-proxy issues发布了一些帖子之后,感谢riccardo.cardin,我能够让它工作。 我已决定发布完整示例以节省您的时间。 以下示例使用服务器express,body-parser(req.body中间件)和当前http-proxy代理并转发请求到第三方服务器。
const webapitargetUrl = 'https://posttestserver.com/post.php';
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // support json encoded bodies
var https = require('https');
var stamproxy = httpProxy.createProxyServer({
target: 'https://localhost:8888',
changeOrigin: true,
agent : https.globalAgent,
toProxy : true,
secure: false,
headers: {
'Content-Type': 'application/json'
}
});
stamproxy.on('proxyReq', function(proxyReq, req, res, options) {
console.log("proxying for",req.url);
if (req.body) {
console.log("prxyReq req.body: ",req.body);
// modify the request. Here i just by removed ip field from the request you can alter body as you want
delete req.body.ip;
let bodyData = JSON.stringify(req.body);
// in case if content-type is application/x-www-form-urlencoded -> we need to change to application/json
proxyReq.setHeader('Content-Type','application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
// stream the content
console.log("prxyReq bodyData: ",bodyData);
proxyReq.write(bodyData);
}
console.log('proxy request forwarded succesfully');
});
stamproxy.on('proxyRes', function(proxyRes, req, res){
proxyRes.on('data' , function(dataBuffer){
var data = dataBuffer.toString('utf8');
console.log("This is the data from target server : "+ data);
});
});
app.use(compression());
app.use(favicon(path.join(__dirname, '..', 'static', 'favicon.ico')));
app.use(Express.static(path.join(__dirname, '..', 'static')));
var sessions = require("client-sessions");
app.use(sessions({
secret: 'blargadeeblargblarg',
cookieName: 'mysession'
}));
app.use('/server/setserverip', (req, res) => {
console.log('------------ Server.js /server/setserverip ---------------------------------');
req.mysession.serverip += 1;
console.log('session data:');
console.log(req.mysession.serverip)
console.log('req.body:');
console.log(req.body);
// Proxy forwarding
stamproxy.web(req, res, {target: webapitargetUrl});
console.log('After calling proxy serverip');
});
答案 5 :(得分:0)
我在 post , put 和 删除时遇到了这个问题> ,但在从 chimurai阅读this issue之后
/
http-proxy-middleware ,我已经做到了。
1-添加 onProxyReq :https://github.com/chimurai/http-proxy-middleware/issues/40#issuecomment-249430255
2-请注意,您必须将 Content-Type:application / json 添加到请求的标头
3-正文解析器的更改顺序