Узел обратной маршрутизации основных маршрутов выдачи

У меня есть 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);
Другие вопросы по тегам