Каждый HTTP-клиент Node.js работает с прокси по-своему, и половина из них вообще не умеет аутентификацию прокси без вспомогательного пакета. axios в некоторых версиях молча игнорирует собственную опцию proxy для HTTPS-целей, у нативного fetch опции прокси нет вовсе, а сообщения об ошибках — ECONNRESET, 407 или просто зависание — не говорят вам ничего.
Это полный рабочий справочник по маршрутизации axios, got, node-fetch, нативного fetch (undici) и superagent через аутентифицированные резидентные прокси. Это Node-компаньон к нашим Python-гайдам (requests/httpx/aiohttp, Scrapy). Все примеры используют стандартный формат-плейсхолдер — подставьте свои реальные учётные данные:
socks5h://USERNAME:[email protected]:913
Не используйте встроенные опции proxy. Используйте прокси-агент. HTTP-клиенты Node делегируют управление соединением объекту-«агенту», и пакеты-агенты (https-proxy-agent, socks-proxy-agent) корректно реализуют CONNECT-туннелирование и аутентификацию. Встроенные опции часто — нет; конфиг proxy в axios — самый печально известный пример.
npm install socks-proxy-agent https-proxy-agent
const axios = require("axios");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const res = await axios.get("https://api.ipify.org?format=json", {
httpAgent: agent, // для http:// целей
httpsAgent: agent, // для https:// целей
proxy: false, // ВАЖНО: отключить собственную обработку прокси в axios
});
console.log(res.data); // -> исходящий IP прокси
Две вещи, которые люди упускают: нужно задать оба — httpAgent и httpsAgent (axios выбирает по схеме цели), и нужно выставить proxy: false, чтобы axios поверх вашего агента не пытался ещё и применить переменные окружения HTTP_PROXY.
const got = require("got");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const body = await got("https://api.ipify.org?format=json", {
agent: { http: agent, https: agent },
}).json();
Если вы скрапите защищённые цели через got, посмотрите на got-scraping — тот же API плюс генерация браузероподобных заголовков и мимикрия HTTP/2-отпечатка (почему это важно: разбор JA3/JA4).
Встроенный fetch в Node приходит из undici, игнорирует переменные окружения для прокси и не имеет опции agent. Способ undici — это dispatcher:
const { ProxyAgent } = require("undici");
// ProxyAgent от undici говорит на HTTP CONNECT (используйте порт вашего HTTP-прокси)
const dispatcher = new ProxyAgent({
uri: "http://us.jibaoproxy.com:1000",
token: "Basic " + Buffer.from("USERNAME:PASSWORD").toString("base64"),
});
const res = await fetch("https://api.ipify.org?format=json", { dispatcher });
console.log(await res.json());
Замечание: ProxyAgent у undici работает только с HTTP-прокси. Для SOCKS5 с нативным fetch либо поставьте перед ним локальный форвардер, либо используйте клиент, принимающий socks-агенты (axios/got выше).
const fetch = require("node-fetch");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const res = await fetch("https://api.ipify.org?format=json", { agent });
С ротируемым резидентным шлюзом вы не управляете списками IP — шлюз выдаёт вам свежий исходящий на каждое соединение либо удерживает один исходящий на один id сессии. В Node это чисто ложится на один агент на личность:
// Sticky: один и тот же id сессии -> один и тот же исходящий IP между запросами
function identityAgent(sessionId) {
return new SocksProxyAgent(
`socks5h://USERNAME-session-${sessionId}:[email protected]:913`
);
}
// Аккаунт A держит IP A, аккаунт B держит IP B - cookie и IP движутся вместе
const agentA = identityAgent("acct_a");
const agentB = identityAgent("acct_b");
Переиспользуйте агент для пула соединений в рамках одной личности; никогда не делите один агент между личностями. Когда ротировать, а когда оставаться — отдельная тема, см. sticky или ротируемые сессии.
| Симптом | Причина | Исправление |
|---|---|---|
407 Proxy Authentication Required | Учётные данные не доходят до прокси | Положите user:pass в URL агента, а не в конфиг клиента |
| axios работает на http://, падает на https:// | Задан только httpAgent | Задайте также httpsAgent и proxy: false |
ECONNRESET сразу же | Неверный порт / неверный протокол (HTTP-порт с SOCKS-агентом) | Сопоставьте тип агента порту |
| Утечки DNS / падают внутренние хостнеймы | socks5:// резолвит DNS локально | Используйте socks5h:// — h отправляет хостнеймы через прокси |
| Нативный fetch игнорирует HTTP_PROXY | undici не читает переменные окружения | Передайте dispatcher явно |
| Локально работает, на целевом сайте 403 | Не баг прокси — TLS-отпечаток | got-scraping или настоящий браузер; см. гайд по TLS |
socks-proxy-agent / https-proxy-agent); никогда не доверяйте встроенным опциям прокси.proxy: false. got: agent: {http, https}. Нативный fetch: dispatcher ProxyAgent из undici.socks5h://, чтобы DNS резолвился через прокси — без утечек.Эндпоинты SOCKS5 + HTTP, sticky или ротация, поценовая оплата за GB — $5 бесплатного баланса, без карты.
Начать бесплатноНовым пользователям — 5U при регистрации, бонус к первому пополнению. Акция ограничена по времени.