为了避免同域AJAX的问题,我想我的node.js的web服务器从URL的所有请求转发/api/BLABLA
到另一台服务器,例如other_domain.com:3000/BLABLA
,并退回到用户同样的事情,这个远程服务器返回的,透明的。
其他所有网址(旁边/api/*
)将被直接送达,没有代理。
如何用Node.js的+ express.js实现这一目标? 你能举一个简单的代码示例?
(包括Web服务器和远程3000
服务器是我的控制之下,无论是运行的node.js与express.js)
到目前为止,我发现这个https://github.com/nodejitsu/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服务器(或最终用户),所以没有运气。
Answer 1:
你想用http.request
创建一个类似的请求发送到远程API,并返回其响应。
事情是这样的:
var http = require('http');
/* your app config here */
app.post('/api/BLABLA', function(req, res) {
var options = {
// host to forward to
host: 'www.google.com',
// port to forward to
port: 80,
// path to forward to
path: '/api/BLABLA',
// request method
method: 'POST',
// headers to send
headers: req.headers
};
var creq = http.request(options, function(cres) {
// set encoding
cres.setEncoding('utf8');
// wait for data
cres.on('data', function(chunk){
res.write(chunk);
});
cres.on('close', function(){
// closed, let's end client request as well
res.writeHead(cres.statusCode);
res.end();
});
cres.on('end', function(){
// finished, let's finish client request as well
res.writeHead(cres.statusCode);
res.end();
});
}).on('error', function(e) {
// we got an error, return 500 error to client and log error
console.log(e.message);
res.writeHead(500);
res.end();
});
creq.end();
});
注意:我还没有真正尝试过上面的,所以它可能包含解析错误希望这会给你一个提示,如何得到它的工作。
Answer 2:
我做了类似的事情,但我用的要求 ,而不是:
var request = require('request');
app.get('/', function(req,res) {
//modify the url in any way you want
var newurl = 'http://google.com/';
request(newurl).pipe(res);
});
我希望这可以帮助,我花了一段时间才能认识到,我能做到这一点:)
Answer 3:
我发现了一个更短的和非常简单的解决方案,以及无缝工作,并与认证,使用express-http-proxy
:
const url = require('url');
const proxy = require('express-http-proxy');
// New hostname+path as specified by question:
const apiProxy = proxy('other_domain.com:3000/BLABLA', {
forwardPath: req => url.parse(req.baseUrl).path
});
然后只需:
app.use('/api/*', apiProxy);
注:如由@MaxPRafferty提到的,使用req.originalUrl
代替baseUrl
保存查询字符串:
forwardPath: req => url.parse(req.baseUrl).path
更新:由于安德鲁(!谢谢)提到的,还有使用相同的原理一个现成的解决方案:
npm i --save http-proxy-middleware
然后:
const proxy = require('http-proxy-middleware')
var apiProxy = proxy('/api', {target: 'http://www.example.org/api'});
app.use(apiProxy)
文档: 在Github上的HTTP代理中间件
我知道我迟到了加入这个派对,但我希望这可以帮助别人。
Answer 4:
为了延长trigoman的答案(完整的信用给他)与邮政合作(也可能使与PUT等工作):
app.use('/api', function(req, res) {
var url = 'YOUR_API_BASE_URL'+ req.url;
var r = null;
if(req.method === 'POST') {
r = request.post({uri: url, json: req.body});
} else {
r = request(url);
}
req.pipe(r).pipe(res);
});
Answer 5:
我用下面的设置直接的一切/rest
到我的后端服务器(8080端口),并且所有其他请求到前端服务器(端口3001的WebPack服务器)。 它支持所有HTTP的方法,不会丢失任何请求元信息和支持WebSockets的(我需要重装热)
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var backend = 'http://localhost:8080',
frontend = 'http://localhost:3001';
app.all("/rest/*", function(req, res) {
apiProxy.web(req, res, {target: backend});
});
app.all("/*", function(req, res) {
apiProxy.web(req, res, {target: frontend});
});
var server = require('http').createServer(app);
server.on('upgrade', function (req, socket, head) {
apiProxy.ws(req, socket, head, {target: frontend});
});
server.listen(3000);
Answer 6:
首先安装Express和HTTP代理中间件
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结束时,我们将它重定向到本地主机:8080。
HTTP://本地主机:3000 / API /登录重定向到HTTP://本地主机:8080 / API /登录
Answer 7:
好吧,这里使用要求(“请求”)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);
});
Answer 8:
我创建了一个非常简单的模块恰好做到这一点: https://github.com/koppelaar/auth-proxy
Answer 9:
我发现了一个更短的解决方案,它正是我想要的https://github.com/nodejitsu/node-http-proxy/
安装完成后http-proxy
npm install http-proxy --save
使用它像下面在服务器/索引/ app.js
var proxyServer = require('http-route-proxy');
app.use('/api/BLABLA/', proxyServer.connect({
to: 'other_domain.com:3000/BLABLA',
https: true,
route: ['/']
}));
我真的花了几天到处寻找,以避免这个问题,尝试大量的解决方案,并没有他们的工作,但这个。
希望这会帮助别人太:)
Answer 10:
我没有有一个明确的样本,而是一个用普通http-proxy
包。 一个非常剥离下来我用我的博客代理的版本。
总之,一切的NodeJS http代理封装在HTTP协议层面,而非TCP(插座)一级的工作。 这也是快递和所有快递中间件如此。 没有人能够做的透明代理,也没有NAT,这意味着保持传入流量的源IP发送到后台Web服务器的数据包。
然而,Web服务器可以从http X转发的摄像头原始IP并将其添加到日志。
该xfwd: true
在proxyOption
启用X转发头功能http-proxy
。
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转发部首: https://en.wikipedia.org/wiki/X-Forwarded-For
我代理的完整版: https://github.com/J-Siu/ghost-https-nodejs-proxy
文章来源: Proxy with express.js