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 Где взять данные прокси

  1. Войдите в кабинет GeekProxy
  2. Откройте план. У планов с оплатой за IP (датацентр, ISP) список адресов, порты, логин и пароль лежат прямо на карточке, а кнопка Export отдаёт весь список текстом
  3. У резидентских и мобильных планов нажмите Options. Панель Proxy Configuration соберёт строку логина с вашей страной, городом и настройками сессии. Готовую строку копируйте из Proxy List

Спецсимволы в пароле внутри URL кодируются процентами. undici и https-proxy-agent раскодируют их перед сборкой заголовка; объект auth у axios берёт значение как есть.

Кабинет GeekProxy, Subscriptions
Кабинет GeekProxy, страница Subscriptions: планы ISP со ссылкой Export, планы Residential Flex и Turbo с кнопками Options и Add GB
Кабинет GeekProxy, Residential Flex
Подписка Residential Flex, панель Proxy Configuration: континент, ASN, ZIP, регион, ОС устройства, тип прокси и TTL сессии, ниже готовая строка curl

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_proxy.js
Редактор: запрос axios с объектом proxy, protocol http и логином-паролем Basic

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());
got_proxy.mjs
Редактор: запрос got с HttpsProxyAgent из hpagent, указывающим на URL GeekProxy

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, зависит от пары версий, и мы это не выясняли.

undici_proxy.mjs
Редактор: undici ProxyAgent с uri и token, зарегистрированный через setGlobalDispatcher

Переменные окружения и 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.

crawlee_proxy.mjs
Редактор: Crawlee ProxyConfiguration с URL GeekProxy и CheerioCrawler с пулом сессий

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.

Не получается? Напишите нам в Telegram, Discord или в чат на сайте. Обычно отвечаем в течение нескольких минут.

Прокси для Node.js

Ротируемые резидентские по HTTP или SOCKS5, либо статические ISP и датацентр без счётчика трафика, выдача за секунды.

Заказать

We use cookies to improve user experience. By clicking "Yes, I agree", you consent to this use of cookies.

Привилегия первых: В честь глобального запуска [мы даем скидку 50%+] на все датацентр тарифы. Эксклюзивное предложение для наших стартовых партнеров.