I need what is essentially a reverse proxy but I need it in Node.js as I will have to put in some custom functionality.
我需要一个反向代理,但我需要它在节点中。我需要加入一些自定义功能。
The gateway
will be the only visible service, and it needs to forward traffic on to an internal network of services. A simple 302 isn't going to work here.
网关将是唯一可见的服务,它需要将通信转发到服务的内部网络。简单的302在这里行不通。
How can I realistically achieve this with Node.js given the asynchronous nature of it?
如何用Node实现这个目标。考虑到它的异步特性?
Are there any well known libraries used for this?
有什么著名的图书馆用来做这个吗?
3 个解决方案
#1
1
With pure core module (may be a bit ugly, but efficient):
纯核心模块(可能有点难看,但效率很高):
var http = require('http');
http.createServer(function (request, response) {
if (request.headers.host === 'api.test') {
// request data from 172.17.0.1:80
} else if (request.headers.host === 'test') {
// request data from 172.17.0.2:80
} else {
// Do something else
}
}).listen(80);
If you don't like this example, you can try: https://www.npmjs.org/package/turtle.io
如果您不喜欢这个示例,可以尝试:https://www.npmjs.org/package/turtle.io
#2
1
I've managed this using node-http-proxy
, where http://first.test/ and http://second.test/ are the hostnames.
我使用了node-http-proxy来管理它,http://first。测试/和http://second。测试/主机名。
var http = require('http'),
httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
// reverse proxy server
http.createServer(function (req, res) {
var target = '';
if (req.headers.host.match(/first.test/)) {
target = 'http://127.0.0.1:8001';
} else if (req.headers.host.match(/second.test/)) {
target = 'http://127.0.0.1:8002';
}
console.log(req.headers.host, '->', target);
proxy.web(req, res, { target: target });
}).listen(8000);
// test server 1
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('8001\n');
res.write(JSON.stringify(req.headers, true, 2));
res.end();
}).listen(8001);
// test server 2
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('8002\n');
res.write(JSON.stringify(req.headers, true, 2));
res.end();
}).listen(8002);
#3
1
For a simple reverse proxy that uses the reactor pattern (like node), I would check out nginx. But, you mentioned you wanted to add in some custom functionality using node, so is that a realistic goal? Absolutely! Here are some things to think about when you are designing your reverse proxy:
对于使用反应器模式(如node)的简单反向代理,我将检查nginx。但是,您提到您想要使用node添加一些自定义功能,所以这是一个现实的目标吗?绝对的!当你在设计反向代理时,你需要考虑以下几点:
- How will you keep track of where incoming requests need to end up? For example, if you proxy all request with /test/* to your UI, but the returned HTML has root relative URLs (/imgs/banner.jpg), how do you keep track of where the subsequent request needs to go (especially if it comes from javascript)? Are you going to tightly couple your proxy and your back end applications? Or you might consider setting a cookie to keep track.
- 您将如何跟踪传入请求需要在何处结束?例如,如果您用/test/*代理所有请求到您的UI,但是返回的HTML具有根相对url (/imgs/banner.jpg),那么如何跟踪后续请求需要去哪里(特别是如果它来自javascript)?您是否要将代理和后端应用程序紧密地结合在一起?或者你可以考虑设置一个cookie来跟踪。
- Does this thing need to scale at all? If your answer is no, my follow up is - are you sure? If you really just need to proxy to two backend applications, I'm sure there are any number of clever ways to achieve that. If at any time you may have N back end applications, then you need a solid plan for managing (add/remove/update) them on the proxy.
- 这个东西需要缩放吗?如果你的答案是不,我的跟进是-你确定吗?如果您真的需要代理到两个后端应用程序,我相信有很多聪明的方法可以实现这一点。如果在任何时候您可能有N个后端应用程序,那么您需要一个可靠的计划来管理(添加/删除/更新)它们在代理上。
- Do your applications use HTTPS? If so, are you going to terminate SSL on the proxy? Can you send data in the clear between your proxy and your back end applications?
- 你的应用程序使用HTTPS吗?如果是,您是否要终止代理上的SSL ?你能在你的代理和你的后端应用之间发送清晰的数据吗?
Good luck on your reverse proxy endeavors! I will update this if anything else occurs to me.
祝你的反向代理好运!如果我有其他事情发生,我会更新这个。
#1
1
With pure core module (may be a bit ugly, but efficient):
纯核心模块(可能有点难看,但效率很高):
var http = require('http');
http.createServer(function (request, response) {
if (request.headers.host === 'api.test') {
// request data from 172.17.0.1:80
} else if (request.headers.host === 'test') {
// request data from 172.17.0.2:80
} else {
// Do something else
}
}).listen(80);
If you don't like this example, you can try: https://www.npmjs.org/package/turtle.io
如果您不喜欢这个示例,可以尝试:https://www.npmjs.org/package/turtle.io
#2
1
I've managed this using node-http-proxy
, where http://first.test/ and http://second.test/ are the hostnames.
我使用了node-http-proxy来管理它,http://first。测试/和http://second。测试/主机名。
var http = require('http'),
httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
// reverse proxy server
http.createServer(function (req, res) {
var target = '';
if (req.headers.host.match(/first.test/)) {
target = 'http://127.0.0.1:8001';
} else if (req.headers.host.match(/second.test/)) {
target = 'http://127.0.0.1:8002';
}
console.log(req.headers.host, '->', target);
proxy.web(req, res, { target: target });
}).listen(8000);
// test server 1
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('8001\n');
res.write(JSON.stringify(req.headers, true, 2));
res.end();
}).listen(8001);
// test server 2
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('8002\n');
res.write(JSON.stringify(req.headers, true, 2));
res.end();
}).listen(8002);
#3
1
For a simple reverse proxy that uses the reactor pattern (like node), I would check out nginx. But, you mentioned you wanted to add in some custom functionality using node, so is that a realistic goal? Absolutely! Here are some things to think about when you are designing your reverse proxy:
对于使用反应器模式(如node)的简单反向代理,我将检查nginx。但是,您提到您想要使用node添加一些自定义功能,所以这是一个现实的目标吗?绝对的!当你在设计反向代理时,你需要考虑以下几点:
- How will you keep track of where incoming requests need to end up? For example, if you proxy all request with /test/* to your UI, but the returned HTML has root relative URLs (/imgs/banner.jpg), how do you keep track of where the subsequent request needs to go (especially if it comes from javascript)? Are you going to tightly couple your proxy and your back end applications? Or you might consider setting a cookie to keep track.
- 您将如何跟踪传入请求需要在何处结束?例如,如果您用/test/*代理所有请求到您的UI,但是返回的HTML具有根相对url (/imgs/banner.jpg),那么如何跟踪后续请求需要去哪里(特别是如果它来自javascript)?您是否要将代理和后端应用程序紧密地结合在一起?或者你可以考虑设置一个cookie来跟踪。
- Does this thing need to scale at all? If your answer is no, my follow up is - are you sure? If you really just need to proxy to two backend applications, I'm sure there are any number of clever ways to achieve that. If at any time you may have N back end applications, then you need a solid plan for managing (add/remove/update) them on the proxy.
- 这个东西需要缩放吗?如果你的答案是不,我的跟进是-你确定吗?如果您真的需要代理到两个后端应用程序,我相信有很多聪明的方法可以实现这一点。如果在任何时候您可能有N个后端应用程序,那么您需要一个可靠的计划来管理(添加/删除/更新)它们在代理上。
- Do your applications use HTTPS? If so, are you going to terminate SSL on the proxy? Can you send data in the clear between your proxy and your back end applications?
- 你的应用程序使用HTTPS吗?如果是,您是否要终止代理上的SSL ?你能在你的代理和你的后端应用之间发送清晰的数据吗?
Good luck on your reverse proxy endeavors! I will update this if anything else occurs to me.
祝你的反向代理好运!如果我有其他事情发生,我会更新这个。