我有 node-reverse-proxy 设置如下:
var options = {
pathnameOnly: true,
router: {
'/myapp': '127.0.0.1:9000',
}
}
httpProxy.createServer(options).listen(8000);
9000 根目录下的 webapp 有一个 index.html 文件,其中包含 stylesheet 这样的链接:
<link rel="stylesheet" href="styles/blue.css">
当我直接点击 localhost:9000 时,会加载html并找到css。然后我通过 localhost:8000 / myapp 的反向代理点击它,但是我得到 错误404 ,因为 localhost :找不到9000 / styles / blue.css ,因为该文件显然是在 localhost:9000 / myapp / styles / blue.css 中提供的。
我的应用程序的html当然不知道反向代理,所以我无法在index.html中解决这个问题。所以我想我缺少一些关于代理设置的基本知识吗?
答案 0 :(得分:1)
我不知道你现在是否找到了解决方法,但我遇到了完全相同的问题,并认为我已经解决了这个问题。
当您直接点击目标端点localhost:9000
时,路径将作为/
发送,即仅发送到根目录。然后,当它请求css等时,它会从根目录中按预期解析那些。
当您通过代理localhost:8000/myapp
进行呼叫时,它会将/myapp
路由到目标,然后将目标服务/
作为路径传递,此时它的行为完全如上所述。
这里的问题实际上是在浏览器上。由于路径指定为/myapp
,因此假定“myapp”是文件名。然后当它请求css等时,它会将其剥离回最后一个斜杠并将其用作所有相对href的基础,这就是为什么它然后要求/styles/blue.css
而不是/myapp/styles/blue.css
。如果您尝试浏览localhost:8000/myapp/
- 请注意尾随斜杠 - 那么它可以正常工作,因为浏览器现在将/myapp/
视为路径的一个组成部分。
显然,您无法指示用户必须添加尾部斜杠。而且你不能轻易在目标服务中做很多事情,只是因为它没有看到任何差异,无论如何你不想在每个终端服务中重复相同的解决方案。所以答案似乎是在代理中拦截它。
此示例有效,但可能有更强大的实现方法。它会查找路径的最后部分可能是目录组件的情况,在这种情况下,请求被重定向以强制浏览器使用尾部斜杠重新发出它。它使得基于它的决定看起来不像 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);