TL;DR
- Node.js не имеет встроенной поддержки прокси. Основные модули
http/httpsотправляют запросы напрямую к целевому хосту, если только вы не прикрепите прокси-осведомленныйhttp.Agentили не установите параметры запроса самостоятельно. - Переменные окружения
HTTP_PROXY/HTTPS_PROXYработают только если библиотека, которую вы вызываете, считывает их. Основнойhttp.requestигнорирует их полностью; большинство инструментов командной строки и некоторых HTTP-клиентов считывают их через вспомогательные пакеты, а не автоматически. https-proxy-agentиhttp-proxy-agent– стандартный способ маршрутизации основныхhttp/httpsзапросов через прокси, используя HTTPCONNECTтуннель для HTTPS целей и прямую ретрансляцию для HTTP целей.- Axios напрямую поддерживает объект
proxy(host,port,protocol, необязательныйauth), поэтому большинству проектов на базе Axios не нужен отдельный пакет для агентов HTTP прокси. - Нативный
fetchиundiciмаршрутизируют через прокси с помощьюProxyAgentиsetGlobalDispatcher, что также влияет на глобальныйfetch()в Node, так как с версии 18+ Node построен на undici. - Учётные данные прокси должны находиться в URL прокси или в специальном поле аутентификации, никогда не должны быть закодированы непосредственно в коде приложения, который попадает в систему контроля версий.
- SOCKS5 прокси требуют другого агента (
socks-proxy-agent) потому что основанные наCONNECTHTTP прокси-агенты не понимают взаимодействие SOCKS.
Введение: что значит "прокси" для запроса Node.js
Прокси в Node.js является промежуточным сервером, через который скрипт намеренно направляет исходящий HTTP или HTTPS запрос, вместо того, чтобы подключаться напрямую к целевому хосту. Основные модули http и https Node не были созданы с поддержкой прокси по умолчанию — каждый запрос с прокси в Node.js работает, потому что код (или библиотека) явно указывает запрос на прокси-хост, либо через пользовательский http.Agent, либо через конфигурацию, специфичную для клиента.
Это различие имеет значение, потому что объясняет, почему копирование учебника по прокси, написанного для одного HTTP-клиента, в проект, использующий другой клиент, часто ничего не делает. curl и многие системные инструменты автоматически считывают HTTP_PROXY/HTTPS_PROXY из окружения; http.request в Node этого не делает. Каждая библиотека клиента ниже требует своей собственной явной настройки.
Быстрый обзор
Внедрение учётных данных прокси и логики ротации в каждый запрос легко сделать неправильно вручную — Nstproxy предоставляет стабильную конечную точку шлюза за план, так что ваш код Node.js должен указывать только на один URL прокси.
Установите необходимые пакеты
Node.js включает http, https и (начиная с Node 18) глобальный fetch, поддерживаемый ProxyAgent от undici. Ни один из них не включает код для маршрутизации прокси, так что добавьте пакет агента, который соответствует клиенту, который вы уже используете:
npm install https-proxy-agent http-proxy-agent npm install axios npm install node-fetch@2 npm install undici npm install socks-proxy-agent
Вам не нужны все пять в одном проекте — устанавливайте только пакеты для тех клиентов, которые ваш код на самом деле вызывает. Версия https-proxy-agent 9.1.0 и версия http-proxy-agent 9.1.0 экспортируют именованный класс (HttpsProxyAgent, HttpProxyAgent), а не экспорт по умолчанию, что имеет значение для синтаксиса require/import ниже.
Настройка прокси для основных модулей http/https Node
http-proxy-agent ретранслирует обычные HTTP запросы через прокси; https-proxy-agent открывает HTTP CONNECT туннель через прокси и затем ведет переговоры о TLS с целевым хостом, что требуется для цели HTTPS. Передача полученного агента как опции agent в функции запроса на базе http.Agent — единственное изменение в обычном вызове https.request:
const { HttpsProxyAgent } = require('https-proxy-agent'); const https = require('https'); const agent = new HttpsProxyAgent('http://user:pass@proxy.example.com:8000'); https.get('https://api.example.com/status', { agent }, (res) => { let body = ''; res.on('data', (chunk) => (body += chunk)); res.on('end', () => console.log(res.statusCode, body)); });
Этот пример был запущен на локальном тестовом прокси (Node http.createServer, обрабатывающим CONNECT) и локальной HTTPS цели: запрос вернул 200 и ожидаемое тело JSON через туннель, подтверждая, что поток CONNECT-череда-TLS работает с этой точной версией агента и формой вызова.
Для обычного HTTP (не HTTPS) назначения используйте HttpProxyAgent — он пересылает запрос без обработки рукопожатия CONNECT:
const { HttpProxyAgent } = require('http-proxy-agent'); const http = require('http'); const agent = new HttpProxyAgent('http://proxy.example.com:8000'); http.get('http://api.example.com/status', { agent }, (res) => { let body = ''; res.on('data', (chunk) => (body += chunk)); res.on('end', () => console.log(res.statusCode, body)); });
Запуск неизменённого вызова http.get() против той же цели без параметра agent, и с установленной переменной окружения HTTP_PROXY, подтвердил, что основной http игнорирует переменную окружения — запрос пошёл напрямую к цели вместо прокси. Считайте любой учебник, который говорит вам «просто установите HTTP_PROXY» для основного http/https, неполным; это работает только для инструментов, которые специально читают эту переменную.
Настройка прокси в Axios
Axios (проверен на версии 1.19.0) принимает настройки прокси в виде обычного объекта в конфигурации запроса, при этом не требуется дополнительный пакет агента для прокси с HTTP-типом:
const axios = require('axios'); axios.get('https://api.example.com/status', { proxy: { host: 'proxy.example.com', port: 8000, protocol: 'http', auth: { username: 'user', password: 'pass' }, }, }).then((res) => console.log(res.status, res.data));
Этот запрос был выполнен против того же локального прокси и цели, использованных выше, и вернул 200 с ожидаемым телом, подтверждая, что опция proxy в Axios выполняет туннель CONNECT для HTTPS-цели самостоятельно. Если вам нужны параметры TLS, которые объект proxy в Axios не поддерживает — специальный CA или отключение проверки сертификата для внутреннего тестового хоста — передайте httpsAgent: new https.Agent({...}) вместе с proxy, или полностью замените proxy экземпляром https-proxy-agent, назначенным в httpsAgent.
Axios также по умолчанию уважает переменные окружения HTTP_PROXY/HTTPS_PROXY/NO_PROXY, если не установлено proxy: false в конфигурации запроса — это один из немногих клиентов, где соглашение о переменных окружения работает без вашего кода агента.
Настройка прокси для node-fetch и встроенного fetch/undici
node-fetch (проверен на версии 2.7.0) принимает ту же опцию agent, что и основной http/https, поэтому применяются те же экземпляры http-proxy-agent/https-proxy-agent:
const fetch = require('node-fetch'); const { HttpProxyAgent } = require('http-proxy-agent'); const agent = new HttpProxyAgent('http://proxy.example.com:8000'); fetch('http://api.example.com/status', { agent }) .then((res) => res.json()) .then((json) => console.log(json));
Запускаясь против локального тестового прокси и HTTP-цели, это вернуло ожидаемое тело JSON, подтверждая, что те же классы агентов работают без изменений как в основном http, так и в node-fetch.
Встроенный глобальный fetch() Node (доступен с Node 18) и отдельный пакет undici не принимают опцию agent таким же образом — они используют собственный ProxyAgent от undici, зарегистрированный глобально с помощью setGlobalDispatcher:
const { ProxyAgent, setGlobalDispatcher } = require('undici'); setGlobalDispatcher(new ProxyAgent('http://proxy.example.com:8000')); const res = await fetch('https://api.example.com/status'); console.log(res.status, await res.json());
Это было запущено с версией undici 6.28.0: после вызова setGlobalDispatcher как undici.request(), так и глобальный fetch() Node маршрутизировались через локальный тестовый прокси и вернули ожидаемый ответ 200 — подтверждая, что setGlobalDispatcher влияет на глобальный fetch, а не только на собственные функции запросов undici, потому что реализация fetch в Node строится на undici. Ограничьте ProxyAgent для одного запроса вместо того, чтобы устанавливать его глобально, когда только некоторые запросы в процессе должны проходить через прокси — передайте { dispatcher: new ProxyAgent(...) } в качестве опции для каждого вызова undici.request().
Продвинутые паттерны: аутентификация, SOCKS5 и ротация
Аутентификация прокси. Для всех четырёх клиентов выше встраивайте учетные данные в URL прокси (http://user:pass@proxy.example.com:8000) или в специальное поле аутентификации клиента (поле auth прокси в Axios). Никогда не форматируйте их в собственный заголовок Authorization запроса к цели — этот заголовок направляется на сервер назначения, а не на прокси, и большинство прокси-серверов ожидают учетные данные в заголовке Proxy-Authorization, который пакеты агентов строят для вас из информации пользователя в URL.
SOCKS5 прокси. https-proxy-agent и http-proxy-agent реализуют только HTTP-протокол прокси CONNECT. Для использования SOCKS5 требуется socks-proxy-agent, который применяет ту же структуру параметров agent:
const { SocksProxyAgent } = require('socks-proxy-agent'); const https = require('https'); const agent = new SocksProxyAgent('socks5://user:pass@proxy.example.com:1080'); https.get('https://api.example.com/status', { agent }, (res) => { /* ... */ });
Контроль сеансов (постоянные и вращающиеся). Используется ли один и тот же IP для выхода на предыдущий запрос или новый, контролируется шлюзом провайдера прокси, а не Node.js — клиентский код остается неизменным в любом случае. Провайдеры, поддерживающие оба режима, обычно переключают поведение в зависимости от параметра сеанса, добавленного к имени пользователя прокси (ID "липкого сеанса") или на отдельных портах шлюза для постоянных и вращающихся пулов; уточните в документации шлюза конкретного провайдера точное название параметра прежде чем предполагать, что одни конвенции применимы ко всем провайдерам.
Использование Nstproxy с теми же шаблонами
Nstproxy предоставляет конечные точки HTTP/SOCKS5 через Residential Lite Proxies и шесть других продуктовых линий прокси — Residential Prime, Datacenter, Static ISP, IPv6, Unlimited Residential и Mobile — так что код HttpsProxyAgent/Axios proxy/ProxyAgent выше работает, указывая агента на назначенный вам шлюз Nstproxy, хост, порт и учетные данные вместо заполнитель. Nstproxy создан для команд, которым нужно географическое таргетирование, контроль сеансов или более высокий объем запросов, чем может обеспечить один самонастраиваемый прокси, и подходит для задач по скрапингу, мониторингу цен, проверке рекламы и тестированию качества, где один IP-адрес выходного уровня подвержен ограничению по скорости или блокировке.
- Целевое таргетирование по странам и городам — выберите местоположение выхода, добавив параметр местоположения к имени пользователя прокси, не изменяя код клиентского запроса.
- Постоянные или вращающиеся сеансы — удерживайте один IP для многошагового рабочего процесса (вход в систему, а затем постраничная навигация) или меняйте его для каждого запроса, в зависимости от используемого параметра сеанса.
- Шлюзы HTTP и SOCKS5 — тот же клиентский код, показанный выше (основной для
http/node-fetch, нативныйproxyобъект для Axios,ProxyAgentдля undici/fetch) работает с шлюзом Nstproxy без дополнительных изменений.
Подтвердите текущие имена хостов шлюзов, порты и цены на странице цены Residential Lite Proxies перед выделением ресурсов, так как детали и тарифы шлюза могут измениться. Полные параметры шлюза, форматы аутентификации и фрагменты SDK находятся в документации Nstproxy; если вы сначала выбираете между провайдерами прокси، страница сравнения прокси Nstproxy расскажет о различиях в функциях по сравнению с другими провайдерами. Команды, которые связывают трафик прокси с краулером на Node.js, часто централизуют правила маршрутизации и контроль пула — смотрите как менеджер прокси Nstproxy применяется к задачам по сканированию для этого уровня.
Честные ограничения
- Основные
http/httpsиnode-fetchникогда не читаютHTTP_PROXY/HTTPS_PROXYсами по себе — все приведенные выше примеры явно устанавливают прокси в коде, и любое развертывание, полагающееся только на переменную окружения для этих клиентов, тихо обойдет прокси. CONNECTтуннельhttps-proxy-agentдобавляет дополнительный сетевой раунд из-за каждого нового HTTPS соединения по сравнению с прямым запросом; повторное использование соединения (keepAlive: trueна агенте) распределяет эту стоимость на несколько запросов к одному и тому же хосту.- Ни один из приведенных выше пакетов агентов не повторяет неудачное подключение к прокси или автоматически не переключается на другой IP для выхода — эта логика, если она вам нужна, должна быть написана в вашу собственную обертку запроса или предоставлена шлюзом прокси-сервиса.
- Соединения WebSocket требуют собственного прокси-осведомленного управления обновлениями; агенты, показанные здесь, охватывают обычные HTTP/HTTPS циклы запроса/ответа, а не рукопожатие
Upgrade.
Устранение неполадок
ECONNREFUSED или ECONNRESET при подключении через прокси. Подтвердите, что хост и порт прокси доступны напрямую (например, с помощью nc -vz host port), прежде чем предполагать, что код Node.js неправильный — брандмауэр или истекший сеанс прокси выдает ту же ошибку, что и ошибка кода.
Ошибки unable to verify the first certificate или self-signed certificate. Это означает, что клиент проверяет TLS для хоста назначения через туннель и не проходит проверку, обычно потому, что корпоративный или тестовый прокси перехватывает TLS с помощью своего собственного сертификата. Добавьте этот сертификат в доверенное хранилище Node (NODE_EXTRA_CA_CERTS), а не отключайте проверку сертификатов в производственном коде.
Запросы зависают вместо того, чтобы завершаться с ошибкой. Установите явный таймаут на агенте или клиенте (опция timeout в http.request, timeout в Axios) — прокси-серверы, которые тихо игнорируют пакеты вместо возврата ошибки соединения, будут зависать до истечения таймаута сокета по умолчанию на платформе.
Только некоторые запросы используют прокси. Для undici/global fetch, setGlobalDispatcher применяется ко всем последующим вызовам в процессе; если некоторые вызовы неожиданно обходят прокси, проверьте, использует ли этот код другой HTTP-клиент (Axios, node-fetch), которому нужна отдельная конфигурация прокси.
Заключение
Каждая настройка прокси в Node.js сводится к одному и тому же решению: какой HTTP-клиент выполняет запрос и какой из поддерживаемых им механизмов прокси — явный http.Agent, объект конфигурации proxy или глобальный диспетчер — вы настраиваете с адресом назначения, портом и учетными данными. Ядро http/https и node-fetch нуждаются в агенте от https-proxy-agent/http-proxy-agent/socks-proxy-agent; Axios принимает объект proxy напрямую; родной fetch и undici используют ProxyAgent и setGlobalDispatcher. Ни один из них не работает только через переменную окружения HTTP_PROXY, если конкретный клиент не указывает, что читает её.
ЧаВо
В: Поддерживает ли Node.js прокси из коробки?
Нет — ядро http и https соединяются напрямую с хостом назначения, если запрос явно не использует прокси-ориентированный http.Agent (из пакета, такого как https-proxy-agent), или библиотека клиента не имеет собственной конфигурации прокси, как опция proxy в Axios.
В: Почему установка HTTP_PROXY не работает в моем скрипте Node.js?
Установка HTTP_PROXY работает только для клиентов, которые специально читают её — Axios читает её по умолчанию, но ядро http/https и node-fetch не делают этого, поэтому им нужен явный агент в коде независимо от переменных окружения.
В: В чем разница между http-proxy-agent и https-proxy-agent?
http-proxy-agent передает обычный HTTP-запрос через прокси без туннеля, в то время как https-proxy-agent сначала открывает HTTP CONNECT туннель через прокси, а затем устанавливает TLS с HTTPS-целевым хостом — используйте тот, который соответствует схеме вашего целевого хоста, а не схеме вашего прокси.
В: Могу ли я использовать прокси с родным fetch() в Node?
Да — зарегистрируйте undici ProxyAgent с помощью setGlobalDispatcher() перед вызовом fetch(), так как встроенный fetch в Node работает на undici и использует тот же глобальный диспетчер.
В: Нужна ли мне другая настройка для прокси SOCKS5?
Да — https-proxy-agent и http-proxy-agent реализуют только HTTP CONNECT протокол прокси, поэтому конечная точка SOCKS5 нуждается в socks-proxy-agent, используя тот же шаблон опции agent.
В: Безопасно ли закодировать учетные данные прокси в моем коде Node.js?
Нет — храните имена пользователей и пароли прокси в переменных окружения или менеджере секретов и формируйте URL прокси во время выполнения, так же, как вы обрабатываете пароль базы данных, а не фиксируйте их в системе контроля версий.
В: Замедляет ли прокси мои запросы в Node.js?
Запрос HTTPS через HTTP CONNECT туннель добавляет одну дополнительную круговую поездку для установки туннеля по сравнению с прямым соединением, но включение keepAlive на агенте позволяет последующим запросам к тому же хосту повторно использовать этот туннель, а не повторно нести затраты.



