Настройка прокси в node-fetch

Прокси в node-fetch и встроенном fetch Node.js: HttpsProxyAgent в опции agent, ProxyAgent из undici в dispatcher, порты 823 и 10000–20000.

Обновлено · Редакция Prokso

Данные для подключения
Хост
gw.prokso.com
Порт
823 HTTP · 824 SOCKS5 — новый IP на каждый запрос · 10000–20000 фиксированный IP (sticky-сессия), HTTP(S) и SOCKS5
Логин и пароль
в кабинете, на странице плана

Готовые строки в нужном формате генерирует кабинет: выберите страну, тип IP и протокол.

Коротко
  • Хост — gw.prokso.com, порты 823 (HTTP), 824 (SOCKS5), 10000–20000 (фиксированный IP, HTTP или SOCKS5)
  • Логин и пароль — в кабинете на странице плана
  • Проверяйте IP в ответе самого запроса через прокси: страница «Мой IP» в браузере ваш скрипт не проверяет
Прокси в node-fetch: короткая видеоинструкция · 0:33

Пошаговая инструкция, как подключить прокси Prokso в node-fetch. Займёт несколько минут.

Шаг 1. Возьмите данные прокси в кабинете

Откройте план и скопируйте хост gw.prokso.com, порт, логин и пароль. Порт 823 — HTTP, 824 — SOCKS5 (оба дают новый IP на каждый запрос); порты 10000–20000 — фиксированный IP до 120 минут, работают и как HTTP, и как SOCKS5 (каждый порт — отдельный адрес). Страну задают в логине: логин__cr.ua.

Блок «Доступ» на странице плана: хост, порты, логин и пароль для строки прокси
Блок «Доступ» на странице плана: хост, порты, логин и пароль для строки прокси

Шаг 2. Установите пакеты

Нужны node-fetch и https-proxy-agent: npm i node-fetch https-proxy-agent.

Шаг 3. Передайте агент прокси в запрос

Создайте HttpsProxyAgent с адресом прокси и передайте его в опции agent. Сохраните код в файл с расширением .mjs и запустите через node.

import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://ЛОГИН:ПАРОЛЬ@gw.prokso.com:823");
const res = await fetch("https://api.ipify.org?format=json", { agent });
console.log(await res.json());
Пример запуска: в выводе — IP прокси, а не ваш. На порту 823 каждый запуск даёт новый адрес
Пример запуска: в выводе — IP прокси, а не ваш. На порту 823 каждый запуск даёт новый адрес

Шаг 4. Встроенный fetch в Node.js 18 и новее

Встроенный fetch опцию agent не принимает. Для него установите undici (npm i undici) и передайте ProxyAgent в опции dispatcher.

import { ProxyAgent } from "undici";

const dispatcher = new ProxyAgent("http://ЛОГИН:ПАРОЛЬ@gw.prokso.com:823");
const res = await fetch("https://api.ipify.org?format=json", { dispatcher });
console.log(await res.json());

Шаг 5. Выберите порт под задачу

Порт 823 — новый IP на каждый запрос, порты 10000–20000 — один и тот же адрес до 120 минут. Для SOCKS5 возьмите пакет socks-proxy-agent и порт 824 или фиксированный порт.

Шаг 6. Проверьте вывод

Запустите пример: скрипт обращается к https://api.ipify.org и печатает IP, который видит сайт. Это должен быть адрес прокси, а не ваш. Ошибка 407 означает неверный логин или пароль. Страница «Мой IP» в браузере здесь не поможет: браузер идёт напрямую.

Тайм-аут и повторы

У fetch нет тайм-аута по умолчанию: зависший запрос будет ждать бесконечно. Задавайте предел через AbortSignal.timeout() и повторяйте только временные сбои:

import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USERNAME:PASSWORD@gw.prokso.com:823");

async function get(url, tries = 3) {
  for (let i = 1; i <= tries; i++) {
    try {
      const res = await fetch(url, { agent, signal: AbortSignal.timeout(30000) });
      if (![502, 503, 504].includes(res.status)) return res;   // retry only temporary failures
    } catch (e) {
      if (i === tries) throw e;
    }
    await new Promise((r) => setTimeout(r, 1000 * i));          // growing pause
  }
  throw new Error("no response after retries");
}

console.log(await (await get("https://prokso.com/ip")).text());

На порту 823 каждый повтор уходит с нового IP. Коды 403 и 429 повторять сразу не стоит: это ответ сайта, а не сбой соединения.

Один агент на все запросы

Создавайте агент один раз и передавайте его во все запросы. Агент хранит открытые соединения с прокси, и повторные запросы идут быстрее. Новый агент на каждый запрос — это новое соединение и лишняя задержка.

Что означают ошибки

  • Статус 407. Прокси не принял логин или пароль либо на плане закончился трафик.
  • ECONNREFUSED. Опечатка в хосте или порте прокси.
  • AbortError или TimeoutError. Сработал ваш тайм-аут: сайт не ответил вовремя.
  • Запрос ушёл с вашего IP. Вы используете встроенный fetch, а он опцию agent не читает — нужен dispatcher из undici.

Подробнее о кодах ответа — на странице коды ошибок прокси.

Вопросы и ответы

Почему встроенный fetch игнорирует прокси?

Встроенный fetch в Node.js работает на библиотеке undici и не читает опцию agent. Прокси для него задаётся через dispatcher, как в примере с ProxyAgent.

Можно ли задать прокси для всех запросов сразу?

Да: в undici есть функция setGlobalDispatcher — передайте ей ProxyAgent в начале программы, и встроенный fetch пойдёт через прокси без дополнительных опций.

Что выбрать: node-fetch или встроенный fetch?

В новых проектах на Node.js 18 и новее достаточно встроенного fetch с undici. node-fetch имеет смысл, если он уже используется в проекте.

Как закодировать пароль со спецсимволами?

Оберните логин и пароль в <code>encodeURIComponent()</code> при сборке адреса прокси.