节点反向代理基本路由问题

我有像这样设置节点反向代理

var options = { pathnameOnly: true, router: { '/myapp': '127.0.0.1:9000', } } httpProxy.createServer(options).listen(8000); 

9000根目录下的webapp有一个index.html文件, 样式表链接如下:

 <link rel="stylesheet" href="styles/blue.css"> 

当我直接打本地主机:9000的HTML加载和CSS被发现。 然后我通过在localhost:8000 / myapp的反向代理,但是我得到一个错误404,因为localhost:9000 / styles / blue.css没有find ,因为该文件显然是在localhost:9000 / myapp / styles / blue.css

我的应用程序的HTML当然不知道有关反向代理,所以我不能解决这个在index.html。 所以我想我缺less一些基本的代理设置?

我不知道你现在是否已经find了解决方法,但我有完全相同的问题,并认为我已经完成了。

当你直接点击目标端点localhost:9000 ,path通过/ ,也就是根目录发送。 然后,当它请求的CSS等,它从根本上解决这些如预期的那样。

当你通过代理localhost:8000/myapp调用时,它将localhost:8000/myapp路由到目标,然后将目标服务/作为path传递,此时它的行为与上述完全相同。

这里的问题实际上是在浏览器。 因为path被指定为/myapp ,所以假定“myapp”是一个文件名。 然后,当它请求的CSS等,剥离回到最后一个斜杠,并使用它作为所有相关的hrefs的基础,这就是为什么然后要求/styles/blue.css而不是/myapp/styles/blue.css 。 如果您尝试浏览到localhost:8000/myapp/ – 注意结尾的斜杠 – 那么它的工作原理是因为浏览器现在将/myapp/视为path的组成部分。

显然,你不能指定用户必须添加结尾的斜杠。 在目标服务中你不能轻易做到这一点,只是因为它没有任何区别,反正你不想在每一个terminal服务中重复相同的解决scheme。 所以答案似乎是在代理中拦截它。

这个例子是有效的,尽pipe可能有更强大的方法来实现它。 它查找path的最后一部分可能是目录组件的情况,在这种情况下,请求被redirect以强制浏览器用尾部斜线重新发出。 它基于它做出的决定看起来不像filename.ext或已经有一个结尾的斜线:

 httpProxy.createServer(function(req, res, proxy) { var parsed = url.parse(req.url); if(!parsed.pathname.match(/(\w+\.\w+|\/)$/)) { parsed.protocol = 'http'; parsed.host = req.headers.host; parsed.pathname += '/'; res.writeHead(301, {Location: url.format(parsed)}); res.end(); } else { proxy.proxyRequest(req, res); } }, options);