GeekProxy в Node.js: axios, got, undici, node-fetch и Crawlee
Единого переключателя прокси в Node нет. axios берёт объект proxy, got и node-fetch хотят агент, undici несёт свой ProxyAgent и стоит за встроенным fetch, а Crawlee заворачивает всё это в ProxyConfiguration. В гайде самая короткая рабочая форма для каждого, кто из них умеет SOCKS5 с паролем, и как удержать одну сессию на одном выходном IP.
Что нужно: активный план GeekProxy и данные прокси из кабинета. Первый запрос через прокси занимает пару минут на клиент.
Получить прокси1 Перед началом
Низ у всех пяти клиентов общий. Для цели https:// клиент открывает через прокси CONNECT-туннель и делает TLS напрямую с сайтом, поэтому Proxy-Authorization едет только в запросе CONNECT. Для обычной цели http:// запрос уходит прокси в forward-режиме, заголовок стоит на самом запросе. Именно на втором пути старые версии клиентов ошибались, так что держите свежие релизы.
Прокси действует на экземпляр клиента. Весь процесс накрывают только setGlobalDispatcher, флаг Node --use-env-proxy или global-agent; дочерние процессы и тогда остаются снаружи.
SOCKS5 с логином и паролем, по клиентам:
- Опция
proxyу axios: нет. axios с socks-proxy-agent: да - undici: да,
ProxyAgentотдаёт URI socks5: агентуSocks5ProxyAgent(undici 7.23.0 и новее, помечен экспериментальным) - node-fetch: да, через socks-proxy-agent в опции
agent - got: официальная страница про прокси SOCKS не покрывает, мы не проверяли. Считайте got клиентом только для HTTP
- Crawlee: нет. Браузерные краулеры гоняют Chromium, а в нём нет авторизации SOCKS. Только HTTP-строки
Keep-alive агенты держат TCP-соединение, а на ротируемом шлюзе выходной IP живёт столько же, сколько соединение. Так и задумано.
Что понадобится
- Активный план GeekProxy (резидентские, ISP или датацентр)
- Данные прокси из кабинета: хост, порт, логин, пароль
- Node 18 или новее. Флагу
--use-env-proxyнужен Node 24.5 или 22.21, SOCKS-агенту undici нужен undici 7.23.0
- Поле Откуда взять
- Протокол HTTP (SOCKS5 там, где в списке выше «да»)
- Хост IP или имя шлюза из кабинета
- Порт из кабинета
- Логин из кабинета
- Пароль из кабинета
2 Где взять данные прокси
- Войдите в кабинет GeekProxy
- Откройте план. У планов с оплатой за IP (датацентр, ISP) список адресов, порты, логин и пароль лежат прямо на карточке, а кнопка Export отдаёт весь список текстом
- У резидентских и мобильных планов нажмите Options. Панель Proxy Configuration соберёт строку логина с вашей страной, городом и настройками сессии. Готовую строку копируйте из Proxy List
Спецсимволы в пароле внутри URL кодируются процентами. undici и https-proxy-agent раскодируют их перед сборкой заголовка; объект auth у axios берёт значение как есть.
3 axios, got и node-fetch
axios: опция proxy
axios принимает объект proxy с полями protocol, host, port и блоком auth для HTTP Basic. README говорит прямо: auth значит Basic-авторизацию на прокси. Опция только для Node.js, в браузерной сборке её нет.
const axios = require('axios');
const res = await axios.get('https://ipinfo.io/json', {
proxy: {
protocol: 'http', // соединение с прокси, а не с целью
host: 'IP',
port: PORT,
auth: { username: 'LOGIN', password: 'PASSWORD' },
},
});
console.log(res.data);
protocol это ошибка номер один. Поле описывает соединение с прокси, а не сайт, который вы запрашиваете. Порты GeekProxy обычные HTTP-прокси, поэтому 'http' даже для целей https://; с 'https' axios откроет TLS к прокси и упадёт. Ещё два факта из README. axios по умолчанию читает http_proxy, https_proxy и no_proxy, а proxy: false это выключает. И ставьте axios 1.17 или новее. Версия 1.16.1 (13 мая 2026) закрыла случай, когда данные HTTPS-запроса могли уйти HTTP-прокси открытым текстом, а 1.17.0 сохраняет ваши TLS-опции httpsAgent при туннелировании.
axios с агентом, включая SOCKS5
Когда нужен SOCKS5 или один агент на всё, отдайте axios прокси-агент. README говорит, что с HttpsProxyAgent axios оставляет туннель агенту. https-proxy-agent сам читает userinfo из URL и собирает Basic-заголовок, раскодируя обе части.
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent'); // HTTP-прокси
const { SocksProxyAgent } = require('socks-proxy-agent'); // SOCKS5
const agent = new HttpsProxyAgent('http://LOGIN:PASSWORD@IP:PORT');
// const agent = new SocksProxyAgent('socks5h://LOGIN:PASSWORD@IP:PORT');
const client = axios.create({ httpAgent: agent, httpsAgent: agent, proxy: false });
const res = await client.get('https://ipinfo.io/json');
Мы добавляем proxy: false всякий раз, когда в деле агент, чтобы переменные окружения не наложили сверху второй прокси. В README эта связка прямо не прописана; это безопасное умолчание. Для SOCKS схема socks5h: отдаёт DNS прокси.
got
Страница советов got говорит без обиняков: пакет tunnel заброшен, а современный выбор это hpagent, он держит сокеты живыми. Агент задаётся на ключ протокола: https для целей https://, http для остальных. HTTP/2-клиент got прокси не поддерживает, а про переменные окружения страница молчит, так что считайте, что got их не читает.
import got from 'got';
import {HttpsProxyAgent} from 'hpagent';
const body = await got('https://ipinfo.io/json', {
agent: {
https: new HttpsProxyAgent({
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: 256,
maxFreeSockets: 256,
scheduling: 'lifo',
proxy: 'http://LOGIN:PASSWORD@IP:PORT'
})
}
}).json();
console.log(body);
Одна честная оговорка. На странице got URL в proxy показан без логина, а README самого hpagent на предмет userinfo мы не читали. Если 407 не уходит, переведите план на белый список IP и уберите логин.
node-fetch
В node-fetch нет логики прокси и чтения переменных окружения. README документирует один крючок, опцию agent. Туда встаёт любой прокси-агент.
import fetch from 'node-fetch';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://LOGIN:PASSWORD@IP:PORT');
const res = await fetch('https://ipinfo.io/json', { agent });
console.log(await res.json());
4 undici и встроенный fetch
undici это HTTP-движок за глобальным fetch в Node, а npm i undici даёт тот же движок с прикрученным API прокси. ProxyAgent ведёт каждый запрос через HTTP-, HTTPS- или SOCKS5-прокси. Задокументированный пример с авторизацией передаёт хост в uri и готовое значение заголовка в token.
import { setGlobalDispatcher, fetch, ProxyAgent } from 'undici'
const proxyAgent = new ProxyAgent({
uri: 'http://IP:PORT',
token: `Basic ${Buffer.from('LOGIN:PASSWORD').toString('base64')}`,
})
setGlobalDispatcher(proxyAgent)
const response = await fetch('https://ipinfo.io/json')
console.log(await response.json())
Короткая форма: new ProxyAgent('http://LOGIN:PASSWORD@IP:PORT'). Приоритет по документации: token, потом устаревшая опция auth, потом логин и пароль из URI, предварительно раскодированные. Не пишите proxy-authorization в заголовки запроса сами: dispatch бросит на это InvalidArgumentError. На один запрос передавайте в fetch опцию { dispatcher: proxyAgent } вместо глобальной регистрации.
fetch мы импортируем из undici намеренно. Доходит ли setGlobalDispatcher из npm-пакета до встроенного fetch Node, зависит от пары версий, и мы это не выясняли.
Переменные окружения и SOCKS5
EnvHttpProxyAgent (undici 6.14.0 и новее) читает http_proxy, https_proxy и no_proxy, верхний регистр тоже, при обоих вариантах побеждает нижний. Задан только http_proxy: через него идут и HTTP, и HTTPS. Только https_proxy: только HTTPS. Создание агента ничего не делает, пока вы его не зарегистрируете.
import { setGlobalDispatcher, fetch, EnvHttpProxyAgent } from 'undici'
setGlobalDispatcher(new EnvHttpProxyAgent()) // читает https_proxy=http://LOGIN:PASSWORD@IP:PORT
const response = await fetch('https://ipinfo.io/json')
console.log(await response.json())
Socks5ProxyAgent появился в undici 7.23.0 как экспериментальный. Он туннелирует HTTP и HTTPS, принимает URL socks5: или socks: с логином и паролем в userinfo, отдаёт имена хостов прокси для DNS и один раз печатает ExperimentalWarning. ProxyAgent сам делегирует ему URI socks5:.
В ядре Node есть путь и без пакетов: node --use-env-proxy app.js или NODE_USE_ENV_PROXY=1 разбирает HTTP_PROXY, HTTPS_PROXY и NO_PROXY на старте (Node 24.5, 22.21; статус Active Development). Учитываются ли логин и пароль внутри этих переменных, документация CLI не говорит. Проверьте сами или берите EnvHttpProxyAgent, где это описано.
5 Crawlee
Crawlee принимает ваши URL прокси в ProxyConfiguration и перебирает их по кругу. Логин и пароль идут в URL; документация класса использует ровно форму http://user:pass@host, а newUrl() возвращает URL вместе с логином и портом. Запись null означает «без прокси» на этот ход.
import { CheerioCrawler, ProxyConfiguration } from 'crawlee';
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: ['http://LOGIN:PASSWORD@IP:PORT'],
});
const crawler = new CheerioCrawler({
proxyConfiguration,
useSessionPool: true,
persistCookiesPerSession: true,
async requestHandler({ request, proxyInfo, body }) {
console.log(request.url, proxyInfo.url, body.toString());
},
});
await crawler.run(['https://ipinfo.io/json']);
Та же опция работает у HttpCrawler, JSDOMCrawler, PlaywrightCrawler и PuppeteerCrawler. При включённом пуле сессий newUrl(sessionId) каждый раз отдаёт для одной сессии один и тот же URL прокси, а proxyInfo в обработчике показывает, что использовалось. В master persistCookiesPerSession переименован в saveResponseCookies, сверьте имя с установленной версией.
Две ловушки именно Crawlee. Браузерные краулеры запускают браузер с одним прокси, поэтому прокси сессии действует на страницу, только если её браузер запущен с этим же прокси. Лечится через launchContext: { useIncognitoPages: true } (каждая страница получает свой контекст с прокси сессии) или launchContext: { browserPerProxy: true }. А newUrlFunction вызывается один раз на новую сессию, никогда на запрос. Его аргументы в опубликованной документации и в master различаются, так что посмотрите сигнатуру у себя, прежде чем собирать в нём sticky-логин Turbo.
6 Проверка работы
Каждый сниппет выше запрашивает https://ipinfo.io/json. Поле ip должно показать адрес прокси, а не ваш. На ISP или датацентре это адрес из кабинета, на Residential или Turbo любой адрес из пула в выбранной стране.
Вернулся ваш IP, ошибки нет? Значит, клиент прокси не использовал. Обычные подозреваемые: агент got на не том ключе протокола, агент undici создан, но не зарегистрирован, proxy: false у axios без агента.
7 Какой продукт GeekProxy подходит
Парсерам, то есть Crawlee или любому из этих клиентов в цикле, нужны Residential Turbo или Residential Flex: ротация ради охвата, sticky-логин на сессию Crawlee для многошаговых сценариев, везде HTTP. Опрос API, вебхуки и боты, которым неделями нужен один адрес, живут на датацентре IPv4 или статическом ISP как один ProxyAgent или одна настройка proxy, счётчика трафика нет. SOCKS5 только когда его требует библиотека, с socks5h для DNS на стороне прокси. Мобильные нужны целям, которые требуют именно операторскую сеть.
8 Частые проблемы
axios падает сразу на соединении, часто с ошибкой TLS
В объекте proxy стоит protocol: 'https'. Это велит axios говорить TLS с самим прокси. Поставьте 'http'; цель при этом может оставаться https://.
axios идёт через другой прокси, а не через переданный агент
Сверху накладываются переменные окружения. Добавьте proxy: false рядом с httpAgent и httpsAgent.
undici бросает InvalidArgumentError про proxy-authorization
Вы положили заголовок в запрос. Перенесите его в опцию token конструктора или в URI.
Встроенный fetch Node игнорирует dispatcher
Импортируйте fetch из установленного пакета undici, чтобы агент и fetch были из одной копии.
Страницы PlaywrightCrawler в Crawlee выходят не с тем прокси
Браузер запущен с прокси другой сессии. Поставьте useIncognitoPages: true или browserPerProxy: true в launchContext.
Прокси для Node.js
Ротируемые резидентские по HTTP или SOCKS5, либо статические ISP и датацентр без счётчика трафика, выдача за секунды.
Заказать