节点反向代理基本路由问题
我有像这样设置节点反向代理 :
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);