Перенаправить http-запрос с удаленного сервера на локальный сервер с помощью nodejs

В инструменте charles есть функция, позволяющая отображать удаленные запросы:

http://www.charlesproxy.com/documentation/tools/map-remote/

По сути, он может принимать любой запрос к серверу (даже если вы не тот, кто его запускает), а затем делает новый запрос к другому серверу, сохраняя путь и строку запроса. Затем ответ второго сервера перезаписывает ответ первого сервера.

Я просто хочу знать, есть ли модуль узла, который может это сделать. Я пытался использовать http-proxy, но мне кажется, что этот удаленный инструмент карты немного отличается от прокси-сервера, поскольку кажется, что вы должны владеть обоими серверами с прокси-сервером.

РЕДАКТИРОВАТЬ: снова попытался использовать модуль узла http-proxy, но, похоже, не может заставить его работать. Вот мой код:

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

httpProxy.createServer({
    hostnameOnly: true,
    router: {
        'www.stackoverflow.com': 'localhost:9000',
    }
}).listen(80);

// Create your target server
//
http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
  res.end();
}).listen(9000);

Я ожидаю, что когда я перейду на www.stackoverflow.com или www.stackoverflow.com:80, он вместо этого перенаправит меня на мой локальный хост:9000.


person prashn64    schedule 26.01.2014    source источник


Ответы (4)


Нет, то, что вы просите, действительно является простым прокси. И нет, вам не нужно «владеть» обоими серверами для запуска прокси. Вы просто проксируете запрос, и в этот момент вы можете изменить данные по своему усмотрению.

Упомянутый вами прокси-модуль будет работать нормально, и есть много других. Вы также можете сделать это с помощью простой конфигурации Nginx, если хотите.

person Brad    schedule 26.01.2014
comment
Я исследовал немного больше, и не будет ли это чем-то большим, чем простой прокси, а не обратным прокси? - person prashn64; 27.01.2014
comment
@ prashn64 Нет, просто прокси-сервер. Правда в том, что термин обратный прокси в любом случае почти бессмысленен. Обычно этот термин используется, когда вы размещаете прокси-сервер рядом с вашими серверами для балансировки нагрузки (среди прочего). Это всего лишь прокси-сервер. Вы добавили дополнительную информацию к своему вопросу... настроили ли вы запись файла hosts, указывающую www.stackoverflow.com на любой IP-адрес вашего сервера Node.js? - person Brad; 27.01.2014
comment
Если это возможно, я бы предпочел не менять конфигурацию для этого. Разве таблица маршрутизации не должна обрабатывать это в любом случае? - person prashn64; 29.01.2014
comment
Вы тут что-то путаете. Таблицы маршрутизации ничего не делают, кроме установки маршрутов между IP-сетями. Это не имеет абсолютно никакого отношения к разрешению DNS. Если вы хотите, чтобы ваш сервер обрабатывал трафик для www.stackoverflow.com, тогда www.stackoverflow.com должен разрешаться в IP-адрес вашего сервера. Вы можете либо настроить свой DNS-сервер (если вы хотите, чтобы это изменение работало со многими), либо настроить запись в файле hosts (которая переопределяет DNS). В качестве альтернативы настройте обычный прокси-сервер на своем сервере и измените настройки прокси-сервера вашего компьютера, чтобы использовать его. Как, по-твоему, работает Чарльз? - person Brad; 29.01.2014
comment
Ааа ок, это имеет смысл. На самом деле я совершенно не в курсе того, как работает Чарльз, и на данный момент для меня это черный ящик. Таким образом, похоже, что единственный вариант, который заставит это работать на любом компьютере с помощью всего одной команды сервера узла, — это настроить DNS-сервер с правильной конфигурацией? Знаете ли вы, нужен ли мне еще один модуль узла сверху, чтобы справиться с этим? - person prashn64; 01.02.2014
comment
@ prashn64 Чарльз - просто прокси-сервер. Когда вы запускаете его, он устанавливает себя в качестве системного прокси-сервера. Если вы хотите, чтобы другие машины использовали ваш прокси-сервер, вы должны настроить их. Если вы хотите, чтобы ваша машина использовала альтернативные серверы для некоторых адресов без прокси-сервера, вы должны перенастроить используемый ими DNS-сервер. Это не имеет ничего общего с вашим приложением... это зависит от DNS-сервера. На данный момент мне совершенно непонятно, что вы пытаетесь сделать. - person Brad; 01.02.2014

Я сделал этот pastebin со своим решением: http://pastebin.com/TfG67j1x

Сохраните содержимое pastebin как proxy.js. Убедитесь, что вы устанавливаете зависимости в ту же папку, что и файл proxy.js. (npm install http-proxy colors connect util --save)

Когда вы запустите прокси, он будет:

  • запустить новый сервер, прослушивающий 8013, выступающий в роли прокси-сервера;
  • запустите демонстрационный целевой сервер, прослушивающий 9013.

При доступе к демонстрационной цели через прокси он изменяет строку «Ruby» на «nodejitsu» для упрощения тестирования. Если вы находитесь за корпоративным брандмауэром/прокси-сервером, этот сценарий пока не работает.

ОБНОВЛЕНИЕ: проблема с "заголовки уже отправлены" была в строке 32/33. Получается, что на одном и том же соединении произошло несколько ошибок. При возникновении первой ошибки будут отправлены заголовки, при возникновении второй ошибки заголовки уже отправлены; в результате возникает исключение «заголовки уже отправлены», и сервер отключается.

С этим исправлением сервер больше не умирает, но по-прежнему не устраняет источник ошибки, заключающийся в том, что NODE.JS не может получить доступ к вашему целевому сайту. Вы должны находиться за другим прокси/брандмауэром, и NodeJS должен будет перенаправить HTTP-запрос на второй прокси. Если вы обычно используете прокси в своем браузере для подключения к Интернету, мое решение не удастся. Однако вы не указали, что это требование.

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

ОБНОВЛЕНИЕ 2. Вам не следует пытаться получить доступ к http://localhost:8013 напрямую, а установить его в качестве прокси-сервера в своем браузере. Обратите внимание на исходные настройки прокси-сервера вашего браузера (см. выше). Попробуйте и получите доступ, затем http://localhost:9013.

person BogdanBiv    schedule 02.02.2014
comment
Я получаю эту ошибку: http.js:645 throw new Error('Can\'t set headers after they are sent.'); Это из-за проблемы с брандмауэром? - person prashn64; 03.02.2014
comment
^ Это когда я пытаюсь подключиться к локальному хосту: 8013, кстати. - person prashn64; 03.02.2014
comment
Я попробовал ваши обновления и действительно больше не получаю этих ошибок. Тем не менее, я до сих пор не получаю измененный текст Ruby -> nodejitsu. Кроме того, когда я нажимаю stackoverflow.com, меня не перенаправляют на localhost:9013. Я проверил прокси-сервер своего браузера, и, похоже, ничего не было настроено. - person prashn64; 05.02.2014
comment
Прокси-серверы работают, когда они настроены как посредники между вашим браузером и сервером, к которому вы обращаетесь. Вы должны настроить свой браузер на использование прокси-сервера по адресу localhost:8013 перед доступом к stackoverflow.com, иначе вы увидите нормальное поведение браузера. Кажется, вы путаете способ работы прокси-серверов с перенаправлением URL-адресов HTTP (stackoverflow.com/questions/5411538/). С установленным прокси браузер будет вести себя так, как будто содержимое пришло непосредственно с веб-сервера, перенаправление не будет отображаться в графическом интерфейсе (т. е. URL-адрес в адресе не изменится). - person BogdanBiv; 06.02.2014
comment
Давно не виделись... Я до сих пор не знаю, помогли ли вам мои ответы. - person BogdanBiv; 06.02.2014
comment
Мне все еще нужно проверить и посмотреть, будет ли работать настройка браузера на использование прокси-сервера. На выходных будет время проверить. - person prashn64; 07.02.2014

Вы добавили этот прокси в конфигурацию вашего браузера? В противном случае базовая ОС направит ваш запрос напрямую к www.stackoverflow.com, и ваш прокси никак не сможет это перехватить.

person CFrei    schedule 31.01.2014

Не могли бы вы подтвердить, что www.stackoverflow.com вообще попадает в ваше приложение node.app? Имя в настоящее время будет разрешаться в IP-адрес, который ведет вас на этот веб-сайт, поэтому вам нужно было убедиться, что это имя теперь разрешается в ваше приложение node.app. В данном случае это, вероятно, означает редактирование файла hosts.

person Spork    schedule 31.01.2014