为了避免同域AJAX问题,我希望我的node.js web服务器将所有来自URL /api/BLABLA的请求转发到另一个服务器,例如other_domain.com:3000/BLABLA,并透明地将此远程服务器返回的相同内容返回给用户。
所有其他url(除了/api/*)将直接提供,没有代理。
我如何实现这与node.js + express.js?你能给出一个简单的代码示例吗?
(web服务器和远程3000服务器都在我的控制下,都运行node.js与express.js)
到目前为止,我找到了这个https://github.com/http-party/node-http-proxy,但阅读文档并没有让我更明智。最后我得到了
var proxy = new httpProxy.RoutingProxy();
app.all("/api/*", function(req, res) {
console.log("old request url " + req.url)
req.url = '/' + req.url.split('/').slice(2).join('/'); // remove the '/api' part
console.log("new request url " + req.url)
proxy.proxyRequest(req, res, {
host: "other_domain.com",
port: 3000
});
});
但是什么也没有返回到原来的web服务器(或最终用户),所以运气不好。
首先安装express和http-proxy-middleware
npm install express http-proxy-middleware --save
然后在你的server.js中
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
app.use(express.static('client'));
// Add middleware for http proxying
const apiProxy = proxy('/api', { target: 'http://localhost:8080' });
app.use('/api', apiProxy);
// Render your site
const renderIndex = (req, res) => {
res.sendFile(path.resolve(__dirname, 'client/index.html'));
}
app.get('/*', renderIndex);
app.listen(3000, () => {
console.log('Listening on: http://localhost:3000');
});
在本例中,我们在端口3000上为站点提供服务,但是当请求以/api结束时,我们将其重定向到localhost:8080。
http://localhost:3000/api/login重定向到http://localhost:8080/api/login
好的,这里有一个现成的复制粘贴答案,使用require('request') npm模块和一个环境变量*,而不是硬编码的代理):
coffeescript
app.use (req, res, next) ->
r = false
method = req.method.toLowerCase().replace(/delete/, 'del')
switch method
when 'get', 'post', 'del', 'put'
r = request[method](
uri: process.env.PROXY_URL + req.url
json: req.body)
else
return res.send('invalid method')
req.pipe(r).pipe res
javascript:
app.use(function(req, res, next) {
var method, r;
method = req.method.toLowerCase().replace(/delete/,"del");
switch (method) {
case "get":
case "post":
case "del":
case "put":
r = request[method]({
uri: process.env.PROXY_URL + req.url,
json: req.body
});
break;
default:
return res.send("invalid method");
}
return req.pipe(r).pipe(res);
});
我没有一个明确的样本,但一个与普通http代理包。一个非常精简的版本的代理,我用在我的博客。
简而言之,所有nodejs的http代理包都工作在http协议级别,而不是tcp(socket)级别。对于express和所有的express中间件来说也是如此。它们都不能进行透明代理,也不能进行NAT,这意味着将传入流量源IP保存在发送到后端web服务器的数据包中。
但是,web服务器可以从http x转发的报头中提取原始IP并将其添加到日志中。
proxyOption中的xfwd: true使能http-proxy的x-forward报头功能。
const url = require('url');
const proxy = require('http-proxy');
proxyConfig = {
httpPort: 8888,
proxyOptions: {
target: {
host: 'example.com',
port: 80
},
xfwd: true // <--- This is what you are looking for.
}
};
function startProxy() {
proxy
.createServer(proxyConfig.proxyOptions)
.listen(proxyConfig.httpPort, '0.0.0.0');
}
startProxy();
X-Forwarded Header的参考:https://en.wikipedia.org/wiki/X-Forwarded-For
完整版的代理:https://github.com/J-Siu/ghost-https-nodejs-proxy