Как я могу использовать прокси-сервер http с node.js http.Client?

Я хочу сделать исходящий HTTP-вызов из node.js, используя стандартныйhttp.Client, Но я не могу подключиться к удаленному серверу напрямую из моей сети, и мне нужно пройти через прокси.

Как мне указать node.js использовать прокси?

 ddallala28 дек. 2010 г., 18:11
У меня та же проблема. Node.js находится за брандмауэром, и я не могу создать HTTPClient для внешнего веб-сайта.

Ответы на вопрос(17)

Как уже упоминалось здесь, @Renat, проксированный HTTP-трафик приходит в виде довольно обычных HTTP-запросов. Сделайте запрос против прокси, передавполный URL назначения в качестве пути.

var http = require ('http');

http.get ({
    host: 'my.proxy.com',
    port: 8080,
    path: 'http://nodejs.org/'
}, function (response) {
    console.log (response);
});
 Marc10 сент. 2011 г., 17:09
Похоже, это работает, хотя Fiddler называет это нарушением протокола, что говорит о том, что это неправильный HTTP-запрос через прокси ...

Http-пакет 'request', кажется, имеет эту функцию:

https://github.com/mikeal/request

Например, объект запроса 'r' ниже использует localproxy для доступа к своим запросам:

var r = request.defaults({'proxy':'http://localproxy.com'})

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    r.get('http://google.com/doodle.png').pipe(resp)
  }
})

К сожалению, нет никаких «глобальных» значений по умолчанию, так что пользователи библиотек, которые используют это, не могут изменить прокси, если библиотека не проходит через http-опции ...

HTH, Крис

 Jon Madison29 апр. 2015 г., 01:20
http-пакет запроса позволяет вашему коду переключаться между прокси и не прокси-использованием (что весьма полезно на моем ноутбуке).

Возможно, это не та строчка, на которую вы надеялись, но вы могли бы взглянуть наhttp://github.com/nodejitsu/node-http-proxy поскольку это может пролить некоторый свет на то, как вы можете использовать свое приложение с http.Client.

 Jerinaw13 мая 2019 г., 20:51
Как это полезно?

Я думаю, что есть лучшая альтернатива ответам на 2019 год. Мы можем использоватьglobal-tunnel-ng пакет для инициализации прокси и не загрязнятьhttp или жеhttps основанный код везде. Итак, сначала установитеglobal-tunnel-ng пакет:

npm install global-tunnel-ng

Затем измените ваши реализации, чтобы инициализировать прокси-сервер, если это необходимо:

const globalTunnel = require('global-tunnel-ng');

globalTunnel.initialize({
  host: 'proxy.host.name.or.ip',
  port: 8080
});

http://groups.google.com/group/nodejs/browse_thread/thread/d5aadbcaa00c3f7/12ebf01d7ec415c3?lnk=gst&q=proxy#12ebf01d7ec415c3

Судя по ответам из этой темы, вы можете использоватьproxychains чтобы запустить node.js через прокси-сервер:
$ proxychains /path/to/node application.js

Лично я не смог установить ни один изproxychains версии наCygwin / Windows окружающая среда, поэтому не мог проверить это.

Кроме того, они также говорили об использованииподключения прокси но я не смог найти документацию о том, как это сделать.

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

 ddallala29 дек. 2010 г., 17:29
обновление: после некоторых расследований выяснилось, что я не могу построить прокси-цепочки на CygWin, потому что RTLD_NEXT не поддерживается.

Если у вас естьосновной схема аутентификации http Вы должны сделать строку base64myuser:mypassword, а затем добавьте «Basic» в начале. Это ценностьProxy-Authorization заголовок, вот пример:

var Http = require('http');

var req = Http.request({
    host: 'myproxy.com.zx',
    port: 8080,
    headers:{"Proxy-Authorization": "Basic bXl1c2VyOm15cGFzc3dvcmQ="},
    method: 'GET',
    path: 'http://www.google.com/'
    }, function (res) {
        res.on('data', function (data) {
        console.log(data.toString());
    });
});

req.end();

В nodejs вы можете использоватьбуфер кодировать

var encodedData = Buffer.from('myuser:mypassword').toString('base64');

console.log(encodedData);

Например, в браузерах вы можете кодировать в base64, используяbtoa (), полезно в запросах ajax в браузере без настроек прокси, выполняющих запрос через прокси.

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

Как узнать, какая схема принимает прокси-сервер?

Если у нас не настроен пользовательский DNS (который выдает что-то вроде ERR_NAME_NOT_RESOLVED), когда мы выполняем запрос, ответ (код 407) должен сообщить в заголовках ответа, какую схему аутентификации http использует прокси-сервер.

Решение Вопроса

Тим Макфарлейн«sответ был близок к использованию HTTP-прокси.

Использовать HTTP-прокси (для незащищенных запросов) очень просто. Вы подключаетесь к прокси-серверу и делаете запрос в обычном режиме, за исключением того, что часть пути включает полный URL-адрес, а заголовок хоста настроен на хост, к которому вы хотите подключиться.
Тим был очень близок со своим ответом, но он пропустил правильную настройку заголовка хоста.

var http = require("http");

var options = {
  host: "proxy",
  port: 8080,
  path: "http://www.google.com",
  headers: {
    Host: "www.google.com"
  }
};
http.get(options, function(res) {
  console.log(res);
  res.pipe(process.stdout);
});

Для записи его ответ работает сhttp://nodejs.org/ но это потому, что их сервер не заботится о неправильном заголовке хоста.

 Laurent Debricon01 июн. 2013 г., 14:03
если вы получили неверный запрос, укажите путь: '/'
 OJFord04 авг. 2015 г., 14:43
Это изменилось? Даже с конечным пунктом назначения в качестве другого локального сервера, я получаю404и целевой сервер никогда не получает запрос ..
 Andi Giga21 мар. 2016 г., 10:01
Как это может быть достигнуто на глобальном уровне? Я могу сделать это по отдельным запросам, но у меня естьvendor Модули, которые мне также нужно использовать прокси-соединение.
 VVB27 окт. 2017 г., 06:32
Я получаю эту ошибку с кодом выше Ошибка: getaddrinfo ENOTFOUND прокси-прокси: 8080
 HairOfTheDog19 июл. 2012 г., 05:36
@ Gohan См. Ответ Криса ниже для примера того, как подключиться к серверу https через прокси-сервер http.
 Jack M26 окт. 2018 г., 23:43
Даже без использования прокси, это не работает. Я не думаю, что поле "путь" может быть использовано таким образом, я получаю сообщение об ошибке соединения сoptions = { path: "http://www.example.com/", method: "GET", headers: {Host: "www.example.com"}}.
 Gohan30 дек. 2011 г., 10:38
Есть ли способ использовать HTTP-прокси для подключения через порт https? кажется, не имеет простого метода
 Twistleton11 апр. 2014 г., 16:22
Как интегрировать прокси-пользователя и прокси-пароль в блоке параметров?

Ответ Имскулла почти сработал для меня, но мне пришлось внести некоторые изменения. Единственное реальное изменение - это добавление имени пользователя, пароля и установка rejectUnauthorized в false. Я не мог комментировать, поэтому я добавил это в ответ.

Если вы запустите код, он получит заголовки текущих историй в Hacker News, согласно этому руководству:http://smalljs.org/package-managers/npm/

var cheerio = require('cheerio');
var request = require('request');

request({
    'url': 'https://news.ycombinator.com/',
    'proxy': 'http://Username:[email protected]:Port/',
    'rejectUnauthorized': false
}, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        if (response.body) {
            var $ = cheerio.load(response.body);
            $('td.title a').each(function() {
                console.log($(this).text());
            });
       }
    } else {
        console.log('Error or status not equal 200.');
    }
});

Узел должен поддерживать использование переменной окружения http_proxy - поэтому он кроссплатформенный и работает с настройками системы, а не требует настройки для каждого приложения.

Используя предоставленные решения, я бы порекомендовал следующее:

CoffeeScript

get_url = (url, response) ->
  if process.env.http_proxy?
    match = process.env.http_proxy.match /^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i
    if match
      http.get { host: match[2], port: (if match[4]? then match[4] else 80), path: url }, response
      return
  http.get url, response

Javascript

get_url = function(url, response) {
  var match;
  if (process.env.http_proxy != null) {
    match = process.env.http_proxy.match(/^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i);
    if (match) {
      http.get({
        host: match[2],
        port: (match[4] != null ? match[4] : 80),
        path: url
      }, response);
      return;
    }
  }
  return http.get(url, response);
};

использование Чтобы использовать этот метод, просто замените http.get, например, следующий пример записывает страницу индекса google в файл с именем test.htm:

file = fs.createWriteStream path.resolve(__dirname, "test.htm")
get_url "http://www.google.com.au/", (response) ->
  response.pipe file
  response.on "end", ->
    console.log "complete"
 EricLaw06 янв. 2014 г., 21:01
Настройка http_proxy не оказывает никакого влияния на работу Node в Windows.
 Luke06 янв. 2014 г., 23:14
Он должен работать под Windows (это основная система, которую я использую). После установки убедитесь, что вы сбросили сеанс терминала (если он установлен через панель управления, а не установлен). Вы должны быть в состоянии проверить, что он установлен правильно, используя echo% HTTP_PROXY%. Или, что еще лучше, вы должны использовать сам узел, узел -e "console.log (process.env.http_proxy);" Это работало для меня под Windows, так что удачи.

Для использования прокси с https я попробовал совет на этом сайте (используя зависимостьHTTPS-прокси-агент) и у меня это сработало

http://codingmiles.com/node-js-making-https-request-via-proxy/

По сути, вам не нужна явная поддержка прокси. Прокси-протокол довольно прост и основан на обычном протоколе HTTP. Вам просто нужно использовать прокси-хост и порт при соединении с HTTPClient. Пример (из документа node.js):

var http = require('http');
var google = http.createClient(3128, 'your.proxy.host');
var request = google.request('GET', '/',
  {'host': 'www.google.com'});
request.end();
...

Таким образом, вы подключаетесь к своему прокси-серверу, но делаете запрос на http://www.google.com.

 Marc10 сент. 2011 г., 17:18
Это, по-видимому, больше не будет работать с node.js начиная с v5.6, так как они удаленыcreateClient.
 sami15 июн. 2011 г., 11:15
http.createClient устарел, Тим Макфарлейн использует более новый http.get ниже

используйте https-proxy-agent как это

var HttpsProxyAgent = require('https-proxy-agent');
var proxy = process.env.https_proxy || 'other proxy address';
var agent = new HttpsProxyAgent(proxy);

options = {
    //...
    agent : agent
}

https.get(options, (res)=>{...});

Если вам нужно использовать базовую авторизацию для вашего прокси-провайдера, просто используйте следующее:

var http = require("http");

var options = {
    host:       FarmerAdapter.PROXY_HOST,
    port:       FarmerAdapter.PROXY_PORT,
    path:       requestedUrl,
    headers:    {
        'Proxy-Authorization':  'Basic ' + new Buffer(FarmerAdapter.PROXY_USER + ':' + FarmerAdapter.PROXY_PASS).toString('base64')
    }
};

var request = http.request(options, function(response) {
    var chunks = [];
    response.on('data', function(chunk) {
        chunks.push(chunk);
    });
    response.on('end', function() {
        console.log('Response', Buffer.concat(chunks).toString());
    });
});

request.on('error', function(error) {
    console.log(error.message);
});

request.end();
 Alex18 июл. 2016 г., 14:31
где я могу найти "FarmerAdapter"?

Одна вещь, на которую у меня ушло некоторое время, чтобы выяснить это, используйте http для доступа к прокси, даже если вы пытаетесь прокси подключиться к серверу https. Это работает для меня, используя Чарльз (анализатор протокола OSX):

var http = require('http');

http.get ({
    host: '127.0.0.1',
    port: 8888,
    path: 'https://www.google.com/accounts/OAuthGetRequestToken'
}, function (response) {
    console.log (response);
});
 aggsol11 июл. 2013 г., 13:55
+1 Ты спас меня! HTTP к прокси для запроса HTTPS.
 Palani28 авг. 2014 г., 20:53
Выше код не работает для меня, и его отношение к проблемеgithub.com/joyent/node/issues/2474 чтобы проверить ответ koichik, мы должны использовать «method»: «connect» и при событии «connect» мы отправили информацию о пути.

Думаю, я бы добавил этот модуль, который нашел:https://www.npmjs.org/package/global-tunnel, который работал отлично для меня (работал сразу со всем моим кодом и сторонними модулями только с кодом ниже).

require('global-tunnel').initialize({
  host: '10.0.0.10',
  port: 8080
});

Сделайте это один раз, и все http (и https) в вашем приложении будут проходить через прокси.

Поочередно звоню

require('global-tunnel').initialize();

Будет использоватьhttp_proxy переменная окружения

 Neel Basu08 мая 2017 г., 15:47
Это работает для трафика https?
 major-mann11 мая 2017 г., 19:56
@NeelBasu Да, это так
 cesaregb08 февр. 2015 г., 20:36
Это сработало для меня! На самом деле таким образом вы отделяете прокси от кода и используете существующую конфигурацию для npm! это путь, я бы сказал,

Ты можешь использоватьзапросЯ только что обнаружил, что невероятно легко использовать прокси в node.js, просто с одним внешним параметром «прокси», даже более того, он поддерживает HTTPS через прокси http.

var request = require('request');

request({
  'url':'https://anysite.you.want/sub/sub',
  'method': "GET",
  'proxy':'http://yourproxy:8087'
},function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body);
  }
})
 blumonkey29 июн. 2015 г., 15:38
Работал для обоихhttp а такжеhttps в моем случае спасибо большое
 keinabel03 июл. 2015 г., 13:41
Есть идеи, почему это не сработает для внутренних страниц корпорации?
 Igor L.31 мар. 2016 г., 15:23
Вам нужно как-то указать аутентификацию (опубликую здесь, если я это выясню)
 Chanoch11 авг. 2015 г., 10:24
Я удивлен, что внутренние корпоративные страницы находятся за прокси. Вы уверены, что прокси не обходится для внутренних страниц? Это на другом влане?

Я купил частный прокси-сервер, после покупки я получил:

255.255.255.255 // IP address of proxy server
99999 // port of proxy server
username // authentication username of proxy server
password // authentication password of proxy server

И я хотел использовать это.Первый ответ а такжевторой ответ работал только для http (прокси) -> http (место назначения), однако я хотел http (proxy) -> https (место назначения).

И для назначения HTTPS было бы лучше использоватьHTTP туннель непосредственно. Я нашел решениеВот, Финальный код:

const http = require('http')
const https = require('https')
const username = 'username'
const password = 'password'
const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64')

http.request({
  host: '255.255.255.255', // IP address of proxy server
  port: 99999, // port of proxy server
  method: 'CONNECT',
  path: 'kinopoisk.ru:443', // some destination, add 443 port for https!
  headers: {
    'Proxy-Authorization': auth
  },
}).on('connect', (res, socket) => {
  if (res.statusCode === 200) { // connected to proxy server
    https.get({
      host: 'www.kinopoisk.ru',
      socket: socket, // using a tunnel
      agent: false    // cannot use a default agent
    }, (res) => {
      let chunks = []
      res.on('data', chunk => chunks.push(chunk))
      res.on('end', () => {
        console.log('DONE', Buffer.concat(chunks).toString('utf8'))
      })
    })
  }
}).on('error', (err) => {
  console.error('error', err)
}).end()
 Rupali Pemare24 окт. 2018 г., 12:35
Спасибо за ответ. У меня сработало

Ваш ответ на вопрос