Назад к блогу

Настройка прокси в Node.js приложениях: полное руководство с примерами кода

Подробное руководство по интеграции прокси в Node.js: от базовой настройки до продвинутых техник ротации IP и обработки ошибок.

📅14 февраля 2026 г.

При разработке Node.js приложений для парсинга, автоматизации или работы с API часто возникает необходимость использования прокси-серверов. Это позволяет обходить географические ограничения, распределять нагрузку и избегать блокировок по IP. В этом руководстве разберём все способы настройки прокси в Node.js — от базовых до продвинутых техник с ротацией и обработкой ошибок.

Базовые концепции работы с прокси в Node.js

Прокси-сервер в Node.js работает как посредник между вашим приложением и целевым сервером. Когда вы отправляете HTTP-запрос через прокси, ваше приложение сначала подключается к прокси-серверу, который затем перенаправляет запрос на конечный адрес. Это позволяет скрыть реальный IP-адрес вашего сервера и использовать IP-адрес прокси.

В Node.js существует несколько основных способов работы с прокси в зависимости от используемой библиотеки для HTTP-запросов. Наиболее популярные варианты:

  • Встроенные модули http/https — базовый функционал без дополнительных зависимостей
  • Axios — популярная библиотека с удобным API и поддержкой промисов
  • Got — современная альтернатива с TypeScript поддержкой
  • node-fetch — реализация Fetch API для Node.js
  • request — устаревшая, но всё ещё используемая библиотека (не рекомендуется для новых проектов)

Прокси-серверы поддерживают различные протоколы. Для работы с Node.js чаще всего используются:

Протокол Описание Применение
HTTP Базовый протокол для незашифрованных соединений Парсинг, работа с API без SSL
HTTPS Прокси с поддержкой SSL/TLS шифрования Безопасные соединения, работа с защищёнными API
SOCKS5 Универсальный протокол для любого типа трафика WebSocket, UDP, сложные сценарии

Для задач парсинга и автоматизации разработчики часто используют резидентные прокси, так как они имеют реальные IP-адреса домашних пользователей и реже попадают под блокировки со стороны целевых сайтов.

Настройка прокси через встроенный модуль http/https

Node.js предоставляет встроенные модули http и https для работы с HTTP-запросами. Для подключения прокси можно использовать библиотеку http-proxy-agent или https-proxy-agent.

Сначала установите необходимые пакеты:

npm install http-proxy-agent https-proxy-agent

Пример использования HTTP прокси со встроенным модулом:

const http = require('http');
const { HttpProxyAgent } = require('http-proxy-agent');

// Настройки прокси
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpProxyAgent(proxyUrl);

// Опции запроса
const options = {
  hostname: 'api.example.com',
  path: '/endpoint',
  method: 'GET',
  agent: agent,
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  }
};

// Выполнение запроса
const req = http.request(options, (res) => {
  let data = '';
  
  res.on('data', (chunk) => {
    data += chunk;
  });
  
  res.on('end', () => {
    console.log('Response:', data);
  });
});

req.on('error', (error) => {
  console.error('Request failed:', error.message);
});

req.end();

Для HTTPS-соединений используйте https-proxy-agent:

const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);

const options = {
  hostname: 'api.example.com',
  path: '/secure-endpoint',
  method: 'GET',
  agent: agent
};

https.get(options, (res) => {
  let data = '';
  
  res.on('data', (chunk) => {
    data += chunk;
  });
  
  res.on('end', () => {
    console.log('Secure response:', data);
  });
}).on('error', (error) => {
  console.error('HTTPS request failed:', error.message);
});

Этот подход даёт максимальный контроль над запросами, но требует больше кода для обработки промисов и ошибок. Для большинства задач удобнее использовать специализированные библиотеки.

Работа с прокси в библиотеке Axios

Axios — одна из самых популярных библиотек для HTTP-запросов в Node.js. Она предоставляет удобный API для настройки прокси и автоматически обрабатывает промисы.

Установка Axios:

npm install axios

Базовая настройка прокси в Axios выглядит следующим образом:

const axios = require('axios');

// Способ 1: Настройка прокси в конфигурации запроса
axios.get('https://api.example.com/data', {
  proxy: {
    protocol: 'http',
    host: 'proxy-server.com',
    port: 8080,
    auth: {
      username: 'your-username',
      password: 'your-password'
    }
  }
})
.then(response => {
  console.log('Data:', response.data);
})
.catch(error => {
  console.error('Error:', error.message);
});

Для многократного использования одних и тех же настроек прокси удобно создать экземпляр Axios с предустановленной конфигурацией:

const axios = require('axios');

// Создание экземпляра с настройками прокси
const axiosWithProxy = axios.create({
  proxy: {
    protocol: 'http',
    host: 'proxy-server.com',
    port: 8080,
    auth: {
      username: 'your-username',
      password: 'your-password'
    }
  },
  timeout: 10000,
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  }
});

// Использование экземпляра
async function fetchData() {
  try {
    const response = await axiosWithProxy.get('https://api.example.com/data');
    console.log('Response:', response.data);
    return response.data;
  } catch (error) {
    console.error('Request failed:', error.message);
    throw error;
  }
}

fetchData();

Для работы с HTTPS прокси через CONNECT метод можно использовать дополнительные агенты:

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:password@proxy-server.com:8080';
const httpsAgent = new HttpsProxyAgent(proxyUrl);

const axiosInstance = axios.create({
  httpsAgent: httpsAgent,
  timeout: 15000
});

// Использование
axiosInstance.get('https://api.example.com/secure-data')
  .then(response => console.log(response.data))
  .catch(error => console.error(error.message));

Axios автоматически обрабатывает переадресацию и поддерживает интерсепторы для логирования и обработки ошибок, что делает его отличным выбором для проектов с активным использованием прокси.

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

Got — современная альтернатива Axios с отличной поддержкой TypeScript и продвинутыми возможностями обработки ошибок. Node-fetch реализует стандартный Fetch API для Node.js.

Работа с прокси в Got

Установка Got и необходимых агентов:

npm install got https-proxy-agent

Пример настройки прокси в Got:

const got = require('got');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = {
  https: new HttpsProxyAgent(proxyUrl)
};

// Создание экземпляра Got с прокси
const gotWithProxy = got.extend({
  agent: agent,
  timeout: {
    request: 10000
  },
  retry: {
    limit: 3,
    methods: ['GET', 'POST']
  }
});

// Использование
async function fetchWithGot() {
  try {
    const response = await gotWithProxy('https://api.example.com/data');
    console.log('Response:', JSON.parse(response.body));
  } catch (error) {
    console.error('Got request failed:', error.message);
  }
}

fetchWithGot();

Работа с прокси в node-fetch

Node-fetch требует явной настройки агента для работы с прокси:

npm install node-fetch https-proxy-agent
const fetch = require('node-fetch');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);

async function fetchWithProxy() {
  try {
    const response = await fetch('https://api.example.com/data', {
      agent: agent,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
      }
    });
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('Data:', data);
    return data;
  } catch (error) {
    console.error('Fetch failed:', error.message);
    throw error;
  }
}

fetchWithProxy();

Got предоставляет более богатый функционал из коробки (автоматические повторы, таймауты, обработка ошибок), в то время как node-fetch ближе к стандартному Fetch API и подходит для разработчиков, знакомых с браузерным JavaScript.

Подключение SOCKS5 прокси через socks-proxy-agent

SOCKS5 — универсальный протокол прокси, который работает на более низком уровне, чем HTTP/HTTPS. Он поддерживает любой тип трафика, включая UDP и WebSocket соединения. Для работы с SOCKS5 в Node.js используется библиотека socks-proxy-agent.

Установка необходимых пакетов:

npm install socks-proxy-agent

Пример использования SOCKS5 прокси с различными библиотеками:

const { SocksProxyAgent } = require('socks-proxy-agent');
const https = require('https');

// Настройка SOCKS5 прокси с авторизацией
const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const agent = new SocksProxyAgent(proxyUrl);

const options = {
  hostname: 'api.example.com',
  path: '/endpoint',
  method: 'GET',
  agent: agent
};

https.get(options, (res) => {
  let data = '';
  
  res.on('data', (chunk) => {
    data += chunk;
  });
  
  res.on('end', () => {
    console.log('SOCKS5 response:', data);
  });
}).on('error', (error) => {
  console.error('SOCKS5 request failed:', error.message);
});

Использование SOCKS5 с Axios:

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const httpsAgent = new SocksProxyAgent(proxyUrl);
const httpAgent = new SocksProxyAgent(proxyUrl);

const axiosWithSocks = axios.create({
  httpAgent: httpAgent,
  httpsAgent: httpsAgent,
  timeout: 15000
});

async function fetchViaSocks5() {
  try {
    const response = await axiosWithSocks.get('https://api.example.com/data');
    console.log('Data via SOCKS5:', response.data);
    return response.data;
  } catch (error) {
    console.error('SOCKS5 request error:', error.message);
    throw error;
  }
}

fetchViaSocks5();

SOCKS5 прокси особенно полезны для задач, требующих работы с нестандартными протоколами или когда нужна максимальная гибкость. Многие провайдеры предлагают мобильные прокси с поддержкой SOCKS5, что позволяет эмулировать мобильный трафик для работы с мобильными API.

Реализация ротации прокси для распределения нагрузки

При парсинге больших объёмов данных или работе с API, имеющими лимиты на количество запросов с одного IP, необходимо использовать ротацию прокси. Это позволяет распределить запросы между несколькими прокси-серверами и избежать блокировок.

Пример реализации простой ротации прокси:

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');

class ProxyRotator {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
  }
  
  // Получить следующий прокси по круговому принципу
  getNextProxy() {
    const proxy = this.proxyList[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Получить случайный прокси
  getRandomProxy() {
    const randomIndex = Math.floor(Math.random() * this.proxyList.length);
    return this.proxyList[randomIndex];
  }
  
  // Создать Axios экземпляр с текущим прокси
  createAxiosInstance(useRandom = false) {
    const proxyUrl = useRandom ? this.getRandomProxy() : this.getNextProxy();
    const agent = new HttpsProxyAgent(proxyUrl);
    
    return axios.create({
      httpsAgent: agent,
      timeout: 10000,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
      }
    });
  }
}

// Список прокси
const proxyList = [
  'http://user1:pass1@proxy1.example.com:8080',
  'http://user2:pass2@proxy2.example.com:8080',
  'http://user3:pass3@proxy3.example.com:8080',
  'http://user4:pass4@proxy4.example.com:8080'
];

const rotator = new ProxyRotator(proxyList);

// Использование ротации
async function fetchWithRotation(url) {
  const axiosInstance = rotator.createAxiosInstance();
  
  try {
    const response = await axiosInstance.get(url);
    console.log('Success with proxy');
    return response.data;
  } catch (error) {
    console.error('Request failed:', error.message);
    throw error;
  }
}

// Пример массового парсинга с ротацией
async function massiveParsing(urls) {
  const results = [];
  
  for (const url of urls) {
    try {
      const data = await fetchWithRotation(url);
      results.push({ url, success: true, data });
      
      // Задержка между запросами
      await new Promise(resolve => setTimeout(resolve, 1000));
    } catch (error) {
      results.push({ url, success: false, error: error.message });
    }
  }
  
  return results;
}

// Запуск парсинга
const urlsToParse = [
  'https://api.example.com/data/1',
  'https://api.example.com/data/2',
  'https://api.example.com/data/3',
  'https://api.example.com/data/4',
  'https://api.example.com/data/5'
];

massiveParsing(urlsToParse)
  .then(results => console.log('Parsing results:', results))
  .catch(error => console.error('Parsing error:', error));

Более продвинутый пример с отслеживанием состояния прокси и автоматическим исключением неработающих:

class AdvancedProxyRotator {
  constructor(proxyList, maxFailures = 3) {
    this.proxyList = proxyList.map(url => ({
      url,
      failures: 0,
      active: true,
      lastUsed: null
    }));
    this.maxFailures = maxFailures;
    this.currentIndex = 0;
  }
  
  // Получить активный прокси
  getActiveProxy() {
    const activeProxies = this.proxyList.filter(p => p.active);
    
    if (activeProxies.length === 0) {
      throw new Error('No active proxies available');
    }
    
    // Поиск прокси, который не использовался дольше всего
    const proxy = activeProxies.reduce((oldest, current) => {
      if (!oldest.lastUsed) return oldest;
      if (!current.lastUsed) return current;
      return current.lastUsed < oldest.lastUsed ? current : oldest;
    });
    
    proxy.lastUsed = Date.now();
    return proxy;
  }
  
  // Отметить прокси как успешный
  markSuccess(proxyUrl) {
    const proxy = this.proxyList.find(p => p.url === proxyUrl);
    if (proxy) {
      proxy.failures = 0;
    }
  }
  
  // Отметить прокси как неудачный
  markFailure(proxyUrl) {
    const proxy = this.proxyList.find(p => p.url === proxyUrl);
    if (proxy) {
      proxy.failures++;
      if (proxy.failures >= this.maxFailures) {
        proxy.active = false;
        console.warn(`Proxy ${proxyUrl} deactivated after ${proxy.failures} failures`);
      }
    }
  }
  
  // Создать Axios экземпляр с ротацией
  async createAxiosInstance() {
    const proxy = this.getActiveProxy();
    const agent = new HttpsProxyAgent(proxy.url);
    
    return {
      instance: axios.create({
        httpsAgent: agent,
        timeout: 10000
      }),
      proxyUrl: proxy.url
    };
  }
  
  // Получить статистику прокси
  getStats() {
    return {
      total: this.proxyList.length,
      active: this.proxyList.filter(p => p.active).length,
      inactive: this.proxyList.filter(p => !p.active).length,
      proxies: this.proxyList.map(p => ({
        url: p.url.replace(/\/\/.*@/, '//***@'), // Скрыть credentials
        active: p.active,
        failures: p.failures
      }))
    };
  }
}

// Использование продвинутого ротатора
const advancedRotator = new AdvancedProxyRotator(proxyList);

async function fetchWithAdvancedRotation(url) {
  const { instance, proxyUrl } = await advancedRotator.createAxiosInstance();
  
  try {
    const response = await instance.get(url);
    advancedRotator.markSuccess(proxyUrl);
    return response.data;
  } catch (error) {
    advancedRotator.markFailure(proxyUrl);
    throw error;
  }
}

// Периодический вывод статистики
setInterval(() => {
  console.log('Proxy stats:', advancedRotator.getStats());
}, 30000);

Такая система автоматически исключает неработающие прокси из ротации и равномерно распределяет нагрузку между активными серверами. Это критически важно при работе с большими объёмами данных.

Обработка ошибок и автоматическое переключение прокси

При работе с прокси неизбежно возникают ошибки: таймауты, отказы соединения, блокировки со стороны целевого сервера. Правильная обработка ошибок и автоматическое переключение на другой прокси повышают надёжность приложения.

Пример реализации системы с автоматическими повторами и переключением прокси:

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');

class ResilientProxyClient {
  constructor(proxyList, maxRetries = 3) {
    this.proxyList = proxyList;
    this.maxRetries = maxRetries;
    this.currentProxyIndex = 0;
  }
  
  // Получить следующий прокси
  getNextProxy() {
    const proxy = this.proxyList[this.currentProxyIndex];
    this.currentProxyIndex = (this.currentProxyIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Определить тип ошибки
  isRetryableError(error) {
    // Ошибки, при которых стоит повторить запрос
    const retryableCodes = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED'];
    const retryableStatuses = [408, 429, 500, 502, 503, 504];
    
    if (error.code && retryableCodes.includes(error.code)) {
      return true;
    }
    
    if (error.response && retryableStatuses.includes(error.response.status)) {
      return true;
    }
    
    return false;
  }
  
  // Выполнить запрос с автоматическими повторами
  async request(url, options = {}, attempt = 1) {
    const proxyUrl = this.getNextProxy();
    const agent = new HttpsProxyAgent(proxyUrl);
    
    const config = {
      ...options,
      httpsAgent: agent,
      timeout: 10000,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        ...options.headers
      }
    };
    
    try {
      console.log(`Attempt ${attempt}/${this.maxRetries} with proxy: ${proxyUrl.replace(/\/\/.*@/, '//***@')}`);
      const response = await axios.get(url, config);
      console.log(`Success on attempt ${attempt}`);
      return response.data;
    } catch (error) {
      console.error(`Attempt ${attempt} failed: ${error.message}`);
      
      // Если достигнут лимит повторов
      if (attempt >= this.maxRetries) {
        console.error(`Max retries (${this.maxRetries}) reached for ${url}`);
        throw error;
      }
      
      // Если ошибка не подлежит повтору
      if (!this.isRetryableError(error)) {
        console.error(`Non-retryable error: ${error.message}`);
        throw error;
      }
      
      // Экспоненциальная задержка перед повтором
      const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
      console.log(`Waiting ${delay}ms before retry...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      
      // Рекурсивный повтор со следующим прокси
      return this.request(url, options, attempt + 1);
    }
  }
  
  // Пакетная обработка URL с обработкой ошибок
  async batchRequest(urls, concurrency = 3) {
    const results = [];
    const queue = [...urls];
    const active = [];
    
    while (queue.length > 0 || active.length > 0) {
      // Запустить новые задачи до достижения лимита параллелизма
      while (active.length < concurrency && queue.length > 0) {
        const url = queue.shift();
        const promise = this.request(url)
          .then(data => ({ url, success: true, data }))
          .catch(error => ({ url, success: false, error: error.message }))
          .finally(() => {
            const index = active.indexOf(promise);
            if (index > -1) active.splice(index, 1);
          });
        
        active.push(promise);
      }
      
      // Дождаться завершения хотя бы одной задачи
      if (active.length > 0) {
        const result = await Promise.race(active);
        results.push(result);
      }
    }
    
    return results;
  }
}

// Использование
const proxyList = [
  'http://user1:pass1@proxy1.example.com:8080',
  'http://user2:pass2@proxy2.example.com:8080',
  'http://user3:pass3@proxy3.example.com:8080'
];

const client = new ResilientProxyClient(proxyList, 3);

// Одиночный запрос
client.request('https://api.example.com/data')
  .then(data => console.log('Data:', data))
  .catch(error => console.error('Final error:', error.message));

// Пакетная обработка
const urls = [
  'https://api.example.com/data/1',
  'https://api.example.com/data/2',
  'https://api.example.com/data/3',
  'https://api.example.com/data/4',
  'https://api.example.com/data/5'
];

client.batchRequest(urls, 3)
  .then(results => {
    const successful = results.filter(r => r.success).length;
    const failed = results.filter(r => !r.success).length;
    console.log(`Completed: ${successful} successful, ${failed} failed`);
    console.log('Results:', results);
  });

Эта реализация включает:

  • Автоматическое переключение на следующий прокси при ошибке
  • Экспоненциальную задержку между повторами (1с, 2с, 4с, 8с, 10с max)
  • Определение типа ошибки для принятия решения о повторе
  • Контроль параллелизма при пакетной обработке
  • Подробное логирование для отладки

Лучшие практики и оптимизация производительности

При работе с прокси в Node.js приложениях следует придерживаться следующих рекомендаций для обеспечения стабильности и производительности:

1. Управление соединениями

Переиспользуйте HTTP агенты вместо создания новых для каждого запроса. Это снижает overhead на установку соединения:

const { HttpsProxyAgent } = require('https-proxy-agent');

// Плохо: создание агента для каждого запроса
async function badExample(url) {
  const agent = new HttpsProxyAgent(proxyUrl);
  return axios.get(url, { httpsAgent: agent });
}

// Хорошо: переиспользование агента
const agent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
  httpsAgent: agent,
  httpAgent: agent
});

async function goodExample(url) {
  return axiosInstance.get(url);
}

2. Настройка таймаутов

Всегда устанавливайте разумные таймауты для предотвращения зависания приложения:

const axiosInstance = axios.create({
  httpsAgent: agent,
  timeout: 10000, // Общий таймаут
  // Детальная настройка таймаутов для Got
  // timeout: {
  //   lookup: 1000,    // DNS lookup
  //   connect: 2000,   // Подключение к прокси
  //   secureConnect: 2000, // SSL handshake
  //   socket: 5000,    // Неактивность сокета
  //   response: 3000,  // Ожидание первого байта ответа
  //   send: 10000,     // Отправка запроса
  //   request: 15000   // Весь запрос
  // }
});

3. Контроль параллелизма

Ограничивайте количество одновременных запросов для предотвращения перегрузки:

const pLimit = require('p-limit');

// Ограничение до 5 одновременных запросов
const limit = pLimit(5);

async function processUrls(urls) {
  const promises = urls.map(url => 
    limit(() => axiosInstance.get(url))
  );
  
  return Promise.allSettled(promises);
}

4. Ротация User-Agent

Комбинируйте ротацию прокси с ротацией User-Agent для большей анонимности:

const userAgents = [
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'
];

function getRandomUserAgent() {
  return userAgents[Math.floor(Math.random() * userAgents.length)];
}

async function fetchWithRandomUA(url) {
  return axiosInstance.get(url, {
    headers: {
      'User-Agent': getRandomUserAgent()
    }
  });
}

5. Мониторинг и логирование

Внедрите систему мониторинга для отслеживания производительности прокси:

class ProxyMonitor {
  constructor() {
    this.stats = new Map();
  }
  
  recordRequest(proxyUrl, success, responseTime) {
    if (!this.stats.has(proxyUrl)) {
      this.stats.set(proxyUrl, {
        total: 0,
        success: 0,
        failed: 0,
        totalResponseTime: 0,
        avgResponseTime: 0
      });
    }
    
    const stat = this.stats.get(proxyUrl);
    stat.total++;
    
    if (success) {
      stat.success++;
      stat.totalResponseTime += responseTime;
      stat.avgResponseTime = stat.totalResponseTime / stat.success;
    } else {
      stat.failed++;
    }
  }
  
  getReport() {
    const report = [];
    
    this.stats.forEach((stat, proxyUrl) => {
      report.push({
        proxy: proxyUrl.replace(/\/\/.*@/, '//***@'),
        successRate: ((stat.success / stat.total) * 100).toFixed(2) + '%',
        avgResponseTime: stat.avgResponseTime.toFixed(0) + 'ms',
        total: stat.total,
        success: stat.success,
        failed: stat.failed
      });
    });
    
    return report;
  }
}

const monitor = new ProxyMonitor();

// Обёртка для запросов с мониторингом
async function monitoredRequest(url, proxyUrl) {
  const startTime = Date.now();
  
  try {
    const response = await axiosInstance.get(url);
    const responseTime = Date.now() - startTime;
    monitor.recordRequest(proxyUrl, true, responseTime);
    return response.data;
  } catch (error) {
    const responseTime = Date.now() - startTime;
    monitor.recordRequest(proxyUrl, false, responseTime);
    throw error;
  }
}

// Периодический отчёт
setInterval(() => {
  console.table(monitor.getReport());
}, 60000);

6. Выбор типа прокси

Выбирайте тип прокси в зависимости от задачи:

Задача Рекомендуемый тип Причина
Массовый парсинг публичных данных Datacenter прокси Высокая скорость, низкая цена
Работа с соцсетями и платформами с защитой Резидентные прокси Реальные IP, низкий риск блокировки
Эмуляция мобильного трафика Мобильные прокси IP мобильных операторов
Работа с нестандартными протоколами SOCKS5 прокси Поддержка любого трафика

Для задач, требующих высокого уровня анонимности и минимального риска блокировок, рекомендуется использовать резидентные прокси. Для высокоскоростного парсинга больших объёмов данных подойдут прокси дата-центров.

7. Безопасность credentials

Никогда не храните учётные данные прокси в коде. Используйте переменные окружения:

// .env файл
PROXY_HOST=proxy-server.com
PROXY_PORT=8080
PROXY_USERNAME=your-username
PROXY_PASSWORD=your-password

// В коде
require('dotenv').config();

const proxyUrl = `http://${process.env.PROXY_USERNAME}:${process.env.PROXY_PASSWORD}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;

// Или для списка прокси
const proxyList = process.env.PROXY_LIST.split(',').map(proxy => proxy.trim());

Заключение

Настройка прокси в Node.js приложениях — важный навык для разработчиков, работающих с парсингом, автоматизацией и интеграцией с внешними API. В этом руководстве мы рассмотрели все основные способы работы с прокси: от базовой настройки через встроенные модули до продвинутых техник с ротацией, обработкой ошибок и мониторингом.

Ключевые моменты, которые стоит запомнить:

  • Выбирайте библиотеку для HTTP-запросов в зависимости от задачи: Axios для универсальности, Got для TypeScript проектов, node-fetch для совместимости с браузерным API
  • Используйте SOCKS5 прокси для работы с нестандартными протоколами и максимальной гибкости
  • Реализуйте ротацию прокси для распределения нагрузки и избежания блокировок
  • Внедрите систему обработки ошибок с автоматическими повторами и переключением прокси
  • Мониторьте производительность прокси и автоматически исключайте неработающие
  • Переиспользуйте HTTP агенты и настраивайте разумные таймауты
  • Храните учётные данные в переменных окружения, а не в коде

При выборе прокси для ваших Node.js приложений учитывайте специфику задачи. Для парсинга защищённых платформ и работы с API, чувствительными к репутации IP, рекомендуем использовать резидентные прокси — они обеспечивают высокий уровень анонимности и минимальный риск блокировок благодаря использованию реальных IP-адресов домашних пользователей.