Я хочу сделать исходящий HTTP-вызов из node.js, используя стандарт http.Client
. Но я не могу подключиться к удаленному серверу напрямую из моей сети, и мне нужно пройти через прокси.
Как мне указать node.js использовать прокси?
Я хочу сделать исходящий HTTP-вызов из node.js, используя стандарт http.Client
. Но я не могу подключиться к удаленному серверу напрямую из моей сети, и мне нужно пройти через прокси.
Как мне указать node.js использовать прокси?
Ответы:
Тим Макфарлейн «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/, но это потому, что их серверу не все равно, что заголовок хоста неверен.
404
, и сервер назначения никогда не получает запрос ..
Вы можете использовать запрос , я только что обнаружил, что невероятно легко использовать прокси на 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);
}
})
http
и https
в моем случае, большое спасибо
Одна вещь, на которую у меня ушло некоторое время, чтобы понять, используйте 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);
});
Как уже упоминалось здесь, @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);
});
Я подумал, что добавлю этот модуль, который я нашел: 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
переменную среды
Я купил частный прокси-сервер, после покупки я получил:
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
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()
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, Крис
По сути, вам не нужна явная поддержка прокси. Прокси-протокол довольно прост и основан на обычном протоколе 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".
Если вам нужно использовать базовую авторизацию для вашего прокси-провайдера, просто используйте следующее:
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();
Узел должен поддерживать использование переменной окружения 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"
Ответ Имскулла почти сработал для меня, но мне пришлось внести некоторые изменения. Единственное реальное изменение - это добавление имени пользователя, пароля и установка 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.');
}
});
Я думаю, что есть лучшая альтернатива ответам по состоянию на 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://github.com/nodejitsu/node-http-proxy, поскольку это может пролить некоторый свет на то, как вы можете использовать свое приложение с http. Клиент.
Судя по ответам из этой ветки, вы можете использовать прокси-цепочки
для запуска node.js через прокси-сервер:
$ proxychains /path/to/node application.js
Лично я не смог установить ни одну из версий прокси-цепочек в среде Cygwin / Windows, поэтому не смог ее протестировать.
Кроме того, они также говорили об использовании connect-proxy, но я не смог найти никакой документации о том, как это сделать.
Короче говоря, я все еще застрял, но, возможно, кто-то может использовать эту информацию, чтобы найти подходящий обходной путь.
Для использования прокси с https я попробовал совет на этом сайте (используя зависимость https-proxy-agent ), и он работал для меня:
http://codingmiles.com/node-js-making-https-request-via-proxy/
Если у вас есть базовая схема http-аутентификации, вы должны создать строку base64 myuser: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 вы можете использовать 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 использует прокси-сервер.