为了避免同域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进行身份验证:
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)
文档:Github上的http-proxy-middleware
我使用下面的设置将/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);
我找到了一个更短、更直接的解决方案,它可以无缝地工作,并且使用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)
文档:Github上的http-proxy-middleware