Я хочу сделать исходящий HTTP-вызов из node.js, используя стандартный http.Client
. Но я не могу подключиться к удаленному серверу напрямую из моей сети, и мне нужно пройти через прокси.
Как мне сказать node.js использовать прокси?
Я хочу сделать исходящий HTTP-вызов из node.js, используя стандартный http.Client
. Но я не могу подключиться к удаленному серверу напрямую из моей сети, и мне нужно пройти через прокси.
Как мне сказать node.js использовать прокси?
Тим Макфарлейн: ответ был близок к использованию прокси-сервера 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
, а целевой сервер никогда не получает запрос ..
- person OJFord; 04.08.2015
vendor
модулей, которые мне также нужно использовать через прокси-соединение.
- person Andi Giga; 21.03.2016
options = { path: "http://www.example.com/", method: "GET", headers: {Host: "www.example.com"}}
.
- person Jack M; 27.10.2018
Вы можете использовать request, я только что обнаружил, что использовать прокси на 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
, большое спасибо
- person Samuel Bushi; 29.06.2015
headers: {'Proxy-Authorization': XXXX}
- person Aaron McKeehan; 27.10.2020
Мне потребовалось время, чтобы понять одну вещь: использовать http для доступа к прокси-серверу, даже если вы пытаетесь прокси-сервером на https-сервер. Это работает для меня, используя Charles (анализатор протокола 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);
});
Купил приватный прокси-сервер, после покупки получил:
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 (прокси) -› https (пункт назначения).
А для назначения https было бы лучше использовать напрямую HTTP-туннель. Я нашел решение здесь.
Узел v8:
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()
Узел v14:
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
const agent = new https.Agent({ socket });
https.get({
host: 'www.kinopoisk.ru',
path: '/',
agent, // 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();
socket
не задокументировано в nodejs. Была ли удалена эта опция.
- person CMCDragonkai; 02.04.2021
socket
не поддерживается функциями get
/ request
модулей http
модулей и просто игнорируется.
- person Damaged Organic; 14.06.2021
Думал, что добавлю этот модуль, который нашел: 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
Кажется, что у 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, Крис
Если вам нужно использовать базовую авторизацию для вашего прокси-провайдера, просто используйте следующее:
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. Вам просто нужно использовать свой прокси-хост и порт при подключении к 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».
Узел должен поддерживать использование переменной окружения 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"
Я думаю, что есть лучшая альтернатива ответам на 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
});
Ответ Имскалла почти сработал для меня, но мне пришлось внести некоторые изменения. Единственное реальное изменение - это добавление имени пользователя, пароля и установка для 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.');
}
});
Просто запустите nodejs с прокси-оболочкой, например tsocks tsocks node myscript.js
Исходное решение: Выполнение HTTP-запросов через прокси-сервер SOCKS5 в NodeJS а>
Дополнительная информация: https://www.binarytides.com/proxify-applications-with-tsocks-and-proxychains-on-ubuntu/
Для Windows: https://superuser.com/questions/319516/how-to-force-any-program-to-use-socks
Возможно, это не тот однострочный текст, на который вы рассчитывали, но вы можете взглянуть на http://github.com/nodejitsu/node-http-proxy, поскольку это может пролить свет на то, как вы можете использовать свое приложение с http.Client.
Для использования прокси с https я попробовал совет на этом веб-сайте (используя зависимость https-proxy-agent), и у меня это сработало:
http://codingmiles.com/node-js-making-https-request-via-proxy/
используйте 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)=>{...});
Если у вас есть Базовый Схема аутентификации http, вы должны сделать строку base64 myuser:mypassword
, а затем добавить "Базовая" в начале. Это значение заголовка 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-аутентификации использует прокси.