Як я можу використовувати проксі-сервер http з node.js http.Client?


137

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

Як мені сказати node.js використовувати проксі?


1
У мене те саме питання. Node.js знаходиться за брандмауером, і я не в змозі створити HTTPClient для зовнішнього веб-сайту.
ddallala

Відповіді:


153

Тім Макфарлейн «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/, але це тому, що їх сервер не хвилює, що заголовок хоста неправильний.


1
Чи є спосіб використання http проксі-з'єднання https-порту? Здається, немає простого методу
Гохан

@Gohan Дивіться відповідь Кріса нижче для прикладу того, як підключитися до https-сервера через та http-проксі.
HairOfTheDog

якщо у вас поганий запит, поставте шлях: '/'
Laurent Debricon

9
Як я можу інтегрувати проксі-користувача та проксі-пароль у блок параметрів?
Твістлтон

Чи змінилося це? Навіть із кінцевим пунктом призначення як іншим локальним сервером я отримую 404, а сервер призначення ніколи не отримує запит ..
OJFord

53

Ви можете використовувати запит , я щойно виявив, що проксі на 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);
  }
})

1
Працював httpі httpsв моєму випадку, велике спасибі
Самуель Буші

якісь ідеї, чому це не працюватиме для внутрішніх сторінок corp?
keinabel

1
Я здивований, що внутрішні сторінки corp стоять за проксі. Ви впевнені, що проксі не обходить внутрішні сторінки? Це на іншому влані?
Ханох

Вам потрібно якось вказати автентифікацію (я опублікую її тут, якщо я це зрозумію)
Ігор Л.

Я отримав цю помилку, використовуючи запит із проксі: Помилка: не вдалося встановити тунельний сокет, причину = підключити ECONNREFUSED 127.0.0.1:80
Federico Caccia

35

Одне, що мені знадобило деякий час, щоб використати "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);
});

1
Наведений вище код не працює для мене, і його пов'язано з видачею github.com/joyent/node/isissue/2474 перевірити відповідь koichik, що ми повинні використовувати "метод": "підключити" та на події "підключити", у нас є інформація про шлях надсилання .
Палані

16

Як вже було сказано @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);
});

2
Це схоже на роботу , хоча Скрипаль називає це порушення протоколу , який передбачає , що це не правильний HTTP запиту через проксі -...
Марк

11

Думав, що я би додав цей модуль, який я знайшов: 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змінну середовища


2
Це працювало для мене! Насправді таким чином ви відокремлюєте проксі від коду і використовуєте існуючу конфігурацію для npm! це я б сказав, я б сказав
cesaregb

@NeelBasu Так, це
майор-манн

10

Я придбав приватний проксі-сервер, після покупки я отримав:

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 (proxy) -> 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
      path: '/your/url'  // specify path to get from server
    }, (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()

7

Пакет http "запит", схоже, має цю функцію:

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)
  }
})

На жаль, немає "глобальних" стандартних значень за замовчуванням, тому користувачі libs, які використовують це, не можуть змінювати проксі, якщо lib не пройде через параметри http ...

HTH, Кріс


пакунок http-запиту полегшує дозвол вашого коду перемикатися між проксі-сервером та непроксі-користуванням (що досить корисно на моєму ноутбуці).
Джон Медісон

5

В основному вам не потрібна явна підтримка проксі. Протокол проксі досить простий і заснований на звичайному протоколі 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".


3
http.createClient застарілий, Тім Макфарлейн використовує новіший http.get нижче
самі

1
Це, мабуть, більше не працюватиме з node.js з версії 5.6, оскільки вони видалили createClient .
Марк

5

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

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();

1
де я можу знайти "FarmerAdapter"?
Алекс

3

Вузол повинен підтримувати використання перемінної середовища 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"

Налаштування http_proxy не має жодного ефекту під час роботи Node в Windows.
EricLaw

Він повинен працювати під Windows (це первинна система, яку я використовую). Переконайтеся, що після встановлення налаштування ви скинули сеанс терміналу (якщо встановлено через панель управління, а не встановлено). Ви повинні мати можливість перевірити, чи встановлено він правильно, використовуючи echo% HTTP_PROXY% Або ще краще, ви повинні використовувати сам вузол -e "console.log (process.env.http_proxy);" Це працювало для мене під Windows, тож удача.
Лука

1

Відповідь Імскулла майже працювала на мене, але мені довелося внести деякі зміни. Єдиною реальною зміною є додавання імені користувача, пароля та налаштування 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:Password@YourProxy: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.');
    }
});

1

Я думаю, що є краща альтернатива відповідям на 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
});

0

Можливо, це не точний єдиний вкладиш, на який ви сподівалися, але ви можете поглянути на http://github.com/nodejitsu/node-http-proxy, оскільки це може пролити трохи світла на те, як можна використовувати ваш додаток із http. Клієнт.


1
Чим це корисно?
Джеріна

0

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 середовищі тому не зміг її перевірити.

Крім того, вони також говорили про використання connect-proxy, але я не зміг знайти жодної документації, як це зробити.

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


оновлення: після деяких розслідувань з'ясувалося, що я не можу створити проксі-ланцюги на CygWin, оскільки RTLD_NEXT не підтримується.
ddallala


0

використовуйте подібний "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)=>{...});

0

Якщо у вас є основна схема автентифікації http, вам потрібно зробити рядок base64 myuser:mypassword, а потім на початку додати "Basic". Це значення заголовка проксі-авторизації , ось приклад:

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 ви можете використовувати Buffer для кодування

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 використовує проксі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.