为了避免同域AJAX问题,我希望我的node.js web服务器将来自URL /api/BLABLA
的所有请求转发到另一个服务器,例如other_domain.com:3000/BLABLA
,并透明地将此远程服务器返回的相同内容返回给用户。
所有其他URL(除/api/*
外)都是直接服务的,没有代理。
如何使用node.js + express.js实现这一点?你能给出一个简单的代码示例吗?
( web服务器和远程3000
服务器都在我的控制之下,都运行带有express.js的node.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服务器(或最终用户),所以没有运气。
发布于 2012-05-04 00:47:49
您希望使用http.request
创建对远程应用程序接口的类似请求并返回其响应。
如下所示:
const http = require('http');
// or use import http from 'http';
/* your app config here */
app.post('/api/BLABLA', (oreq, ores) => {
const 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: oreq.headers,
};
const creq = http
.request(options, pres => {
// set encoding
pres.setEncoding('utf8');
// set http status code based on proxied response
ores.writeHead(pres.statusCode);
// wait for data
pres.on('data', chunk => {
ores.write(chunk);
});
pres.on('close', () => {
// closed, let's end client request as well
ores.end();
});
pres.on('end', () => {
// finished, let's finish client request as well
ores.end();
});
})
.on('error', e => {
// we got an error
console.log(e.message);
try {
// attempt to set error message and http status
ores.writeHead(500);
ores.write(e.message);
} catch (e) {
// ignore
}
ores.end();
});
creq.end();
});
注意:我还没有真正尝试过上面的方法,所以它可能包含解析错误,希望这能给你一个提示,告诉你如何让它工作。
发布于 2015-09-24 16:40:35
我发现了一种更短、更直接的解决方案,它使用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', {
proxyReqPathResolver: req => url.parse(req.baseUrl).path
});
然后简单地说:
app.use('/api/*', apiProxy);
注意:正如@MaxPRafferty所提到的,使用req.originalUrl
代替baseUrl
来保留查询字符串:
forwardPath: req => url.parse(req.baseUrl).path
更新:正如Andrew提到的(谢谢!),有一个现成的解决方案使用了相同的原则:
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)
文档:http-proxy-middleware on Github
我知道我来晚了,但我希望这能帮助到一些人。
发布于 2014-03-11 21:01:00
要将trigoman的回答(完全归功于他)扩展到与POST一起工作(也可以与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);
});
https://stackoverflow.com/questions/10435407
复制相似问题