Узел обратной маршрутизации основных маршрутов выдачи
У меня есть node-reverse-proxy, настроенный так:
var options = {
pathnameOnly: true,
router: {
'/myapp': '127.0.0.1:9000',
}
}
httpProxy.createServer(options).listen(8000);
У веб-приложения в корне 9000 есть файл index.html со ссылкой на таблицу стилей, например:
<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. Итак, я думаю, что я упускаю что-то базовое в настройке прокси??
1 ответ
Я не знаю, нашли ли вы обходной путь для этого, но у меня была точно такая же проблема, и я думаю, что решил ее.
Когда вы попадаете в конечную точку цели напрямую localhost:9000
путь передается как /
т.е. просто корень. Затем, когда он запрашивает CSS и т. Д., Он разрешает их, как и ожидалось, из корня.
При звонке через прокси localhost:8000/myapp
это маршруты /myapp
к цели, а затем передает целевой сервис /
как путь, в котором он ведет себя точно так же, как указано выше.
Проблема здесь на самом деле в браузере. Потому что путь указан как /myapp
, предполагается, что "myapp" является именем файла. Затем, когда он запрашивает css и т. Д., Он очищает его до последней косой черты и использует его в качестве основы для всех относительных hrefs, поэтому он затем запрашивает /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);