Пересылать каждый запрос с помощью node-http-proxy

Я пытаюсь настроить node-http-proxy, который просто перенаправляет запросы. В конце концов, этот прокси должен внедрять javascript на каждый веб-сайт, который я посещаю через браузер.

Сейчас большинство страниц перенаправляются и отображаются правильно, но некоторые, например posterkoenig.ch или verkehrsclub.ch возвращают либо пустую страницу, либо на странице есть ошибка. Оба сайта хорошо работают без прокси. Что мне нужно изменить или что я упускаю, что не пересылается правильно?

Я очень новичок в nodejs и даже не совсем уверен, должен ли мой подход работать или нет.

Вот что у меня есть до сих пор:

var httpProxy = require('http-proxy');
var url = require('url');

httpProxy.createServer(function(req, res, proxy) {

  var urlObj = url.parse(req.url);

  proxy.proxyRequest(req, res, {
    host: urlObj.host,
    port: 80,
    changeOrigin: true,
    enable : { xforward: true }
  });
}).listen(9000, function () {
  console.log("Waiting for requests...");
});

Обновлять

По предложению @robertklep я удалил changeOrigin и переопределил req.headers.host, а также req.headers.url

posterkoenig.ch:

Теперь бросает:

An error has occurred: 
{"code":"ENOTFOUND","errno":"ENOTFOUND","syscall":"getaddrinfo"}

verkehrsclub.ch:

Главная страница теперь работает, но подстраницы по-прежнему выдают ошибку на странице.

var httpProxy = require('http-proxy');
var url = require('url');

httpProxy.createServer(function(req, res, proxy) {

  var urlObj = url.parse(req.url);

  req.headers['host'] = urlObj.host;
  req.headers['url'] = urlObj.href;

  proxy.proxyRequest(req, res, {
    host: urlObj.host,
    port: 80,
    enable : { xforward: true }
  });
}).listen(9000, function () {
  console.log("Waiting for requests...");
});

person greenish    schedule 05.05.2013    source источник
comment
Вы смогли сделать это для HTTPS-сайтов?   -  person everconfusedGuy    schedule 25.07.2013
comment
В принципе, это должно быть возможно. Я не пробовал, но https://github.com/nodejitsu/node-http-proxy#using-https говорит, что поддерживает https. Но ваше приложение node также должно запускать https-сервер, поэтому вам нужен действительный сертификат https и ключ, чтобы он работал. Затем вы сможете использовать небольшое изменение приведенного выше скрипта с https-сервером. Надеюсь, это поможет!   -  person greenish    schedule 25.07.2013
comment
Как вы настроили свой браузер для использования этого прокси? Просто ввели localhost:9000 в качестве адреса веб-прокси-сервера?   -  person Ayush Goel    schedule 15.12.2017


Ответы (1)


Ваша первая проблема связана с changeOrigin: он отправит на удаленный сервер заголовок Host, который включает номер порта, и оба сайта, которые вы упомянули, не могут этого обработать.

Вместо этого попробуйте следующее:

req.headers.host = urlObj.host;
req.url          = urlObj.path;
proxy.proxyRequest(req, res, {
  host: urlObj.host,
  port: 80,
  enable : { xforward: true }
});

Что касается другой вашей проблемы, я думаю, что это может быть связано с веб-сайтами, которые не обслуживают свой контент в формате UTF-8 (это кодировка, которую будет использовать .toString(), если вы не передадите ей кодировку). Это происходит всегда или только с некоторыми сайтами?

Между прочим, harmon — это промежуточное ПО для node-http-proxy, которое обеспечивает удобный способ перезаписи ответов. Это может быть излишним для вашей ситуации, но это также может решить вашу проблему.

EDIT: вот минимальный пример, который, кажется, отлично работает как для posterkoenig.ch, так и для www.verkehrsclub.ch (домашние страницы, а также подстраницы):

var httpProxy = require('http-proxy');
var url       = require('url');

httpProxy.createServer(function(req, res, proxy) {
  var urlObj = url.parse(req.url);

  req.headers.host  = urlObj.host;
  req.url           = urlObj.path;

  proxy.proxyRequest(req, res, {
    host    : urlObj.host,
    port    : 80,
    enable  : { xforward: true }
  });
}).listen(9000, function () {
  console.log("Waiting for requests...");
});
person robertklep    schedule 06.05.2013
comment
Спасибо за ваше время! Я попробовал это, но когда я удаляю флаг ‹code›changeOrigin‹/code›, posterkoenig.ch возвращает Произошла ошибка: {code:ENOTFOUND,errno:ENOTFOUND,syscall:getaddrinfo}. Затем я также переопределил headers.url.. с этим главная страница verkehrsclub.ch отображается правильно, но каждая подстраница по-прежнему не работает.. Я обновил свой код в вопросе - person greenish; 06.05.2013
comment
Ошибка, которую вы получаете для postkoenig.ch, предполагает ошибку DNS, что странно (какое значение urlObj.host в этом случае?). Кроме того, я отредактировал свой ответ, потому что обнаружил еще одну проблему, которая может вызвать вашу вторую проблему. - person robertklep; 06.05.2013
comment
Спасибо, req.url = urlObj.path; сделал свою работу! - person greenish; 07.05.2013
comment
Я попробовал минимальный пример, но он учитывает только запросы, поступающие с 127.0.0.1. Как заставить его также прослушивать запросы, поступающие из внешнего источника? - person Attila Szeremi; 09.10.2013
comment
@SzerémiAttila Я не думаю, что это как-то связано с http-proxy, я протестировал его (запустил прокси-сервер на моем Mac, получил доступ к нему через мой сервер Linux), и он работает как есть. Возможно, у вас есть брандмауэр, который блокирует входящие соединения? - person robertklep; 09.10.2013
comment
@robertklep, вероятно, это брандмауэр, поскольку я тестировал его на другом сервере, над которым у меня было больше контроля, и там он работал. Спасибо! - person Attila Szeremi; 10.10.2013
comment
Какой URL-адрес вы нажмете, чтобы заставить прокси-код узла творить чудеса? - person Andre; 20.05.2016
comment
Это больше не работает, так как теперь обязательно передавать какую-то цель или поле пересылки в опциях. Выполнение приведенного выше кода дает мне «Должен предоставить действительный URL-адрес для цели». @зеленоватый - person Ayush Goel; 15.12.2017
comment
@AyushGoel вместо установки параметров host и port попробуйте использовать target : req.url - person robertklep; 15.12.2017
comment
Нет, это не работает. См. это . Options — это словарь, где target/forward является одним из обязательных полей. - person Ayush Goel; 15.12.2017
comment
Я не смог заставить его работать на всю жизнь. @робертклеп. Если вы знаете, как это может работать с последним кодом библиотеки, можете опубликовать ответ здесь. Большое спасибо - person Ayush Goel; 15.12.2017