Voltar ao blog

Configuração de proxy em aplicações Node.js: guia completo com exemplos de código

Guia detalhado para integrar proxies no Node.js: desde a configuração básica até técnicas avançadas de rotação de IP e tratamento de erros.

📅14 de fevereiro de 2026
```html

Ao desenvolver aplicações Node.js para scraping, automação ou trabalho com APIs, frequentemente surge a necessidade de utilizar servidores proxy. Isso permite contornar restrições geográficas, distribuir a carga e evitar bloqueios por IP. Neste guia, abordaremos todas as formas de configurar proxies em Node.js — desde técnicas básicas até avançadas com rotação e tratamento de erros.

Conceitos básicos de trabalho com proxy em Node.js

Um servidor proxy em Node.js funciona como um intermediário entre sua aplicação e o servidor de destino. Quando você envia uma solicitação HTTP através de um proxy, sua aplicação primeiro se conecta ao servidor proxy, que então redireciona a solicitação para o endereço final. Isso permite ocultar o verdadeiro endereço IP do seu servidor e usar o endereço IP do proxy.

Em Node.js, existem várias maneiras principais de trabalhar com proxies, dependendo da biblioteca utilizada para solicitações HTTP. As opções mais populares incluem:

  • Módulos embutidos http/https — funcionalidade básica sem dependências adicionais
  • Axios — biblioteca popular com uma API conveniente e suporte a promessas
  • Got — alternativa moderna com suporte a TypeScript
  • node-fetch — implementação da Fetch API para Node.js
  • request — biblioteca obsoleta, mas ainda utilizada (não recomendada para novos projetos)

Os servidores proxy suportam vários protocolos. Para trabalhar com Node.js, os mais utilizados são:

Protocolo Descrição Aplicação
HTTP Protocolo básico para conexões não criptografadas Scraping, trabalho com API sem SSL
HTTPS Proxy com suporte a criptografia SSL/TLS Conexões seguras, trabalho com APIs protegidas
SOCKS5 Protocolo universal para qualquer tipo de tráfego WebSocket, UDP, cenários complexos

Para tarefas de scraping e automação, os desenvolvedores frequentemente utilizam proxies residenciais, pois eles possuem endereços IP reais de usuários domésticos e raramente são bloqueados por sites de destino.

Configuração de proxy através do módulo http/https embutido

O Node.js fornece módulos embutidos http e https para trabalhar com solicitações HTTP. Para conectar um proxy, você pode usar a biblioteca http-proxy-agent ou https-proxy-agent.

Primeiro, instale os pacotes necessários:

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

Exemplo de uso de proxy HTTP com o módulo embutido:

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

// Configurações do proxy
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpProxyAgent(proxyUrl);

// Opções da solicitação
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'
  }
};

// Execução da solicitação
const req = http.request(options, (res) => {
  let data = '';
  
  res.on('data', (chunk) => {
    data += chunk;
  });
  
  res.on('end', () => {
    console.log('Resposta:', data);
  });
});

req.on('error', (error) => {
  console.error('Solicitação falhou:', error.message);
});

req.end();

Para conexões HTTPS, use 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('Resposta segura:', data);
  });
}).on('error', (error) => {
  console.error('Solicitação HTTPS falhou:', error.message);
});

Essa abordagem oferece controle máximo sobre as solicitações, mas requer mais código para tratamento de promessas e erros. Para a maioria das tarefas, é mais conveniente usar bibliotecas especializadas.

Trabalho com proxy na biblioteca Axios

Axios é uma das bibliotecas mais populares para solicitações HTTP em Node.js. Ela fornece uma API conveniente para configuração de proxy e trata automaticamente as promessas.

Instalação do Axios:

npm install axios

A configuração básica de proxy no Axios é a seguinte:

const axios = require('axios');

// Método 1: Configuração de proxy na configuração da solicitação
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('Dados:', response.data);
})
.catch(error => {
  console.error('Erro:', error.message);
});

Para reutilizar as mesmas configurações de proxy, é conveniente criar uma instância do Axios com a configuração pré-definida:

const axios = require('axios');

// Criação de instância com configurações de proxy
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'
  }
});

// Uso da instância
async function fetchData() {
  try {
    const response = await axiosWithProxy.get('https://api.example.com/data');
    console.log('Resposta:', response.data);
    return response.data;
  } catch (error) {
    console.error('Solicitação falhou:', error.message);
    throw error;
  }
}

fetchData();

Para trabalhar com proxy HTTPS através do método CONNECT, você pode usar agentes adicionais:

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
});

// Uso
axiosInstance.get('https://api.example.com/secure-data')
  .then(response => console.log(response.data))
  .catch(error => console.error(error.message));

O Axios lida automaticamente com redirecionamentos e suporta interceptadores para registro e tratamento de erros, tornando-o uma excelente escolha para projetos que utilizam intensivamente proxies.

Configuração de proxy em got e node-fetch

Got é uma alternativa moderna ao Axios com excelente suporte a TypeScript e recursos avançados de tratamento de erros. O node-fetch implementa a Fetch API padrão para Node.js.

Trabalho com proxy em Got

Instalação do Got e dos agentes necessários:

npm install got https-proxy-agent

Exemplo de configuração de proxy no 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)
};

// Criação de instância Got com proxy
const gotWithProxy = got.extend({
  agent: agent,
  timeout: {
    request: 10000
  },
  retry: {
    limit: 3,
    methods: ['GET', 'POST']
  }
});

// Uso
async function fetchWithGot() {
  try {
    const response = await gotWithProxy('https://api.example.com/data');
    console.log('Resposta:', JSON.parse(response.body));
  } catch (error) {
    console.error('Solicitação Got falhou:', error.message);
  }
}

fetchWithGot();

Trabalho com proxy em node-fetch

O node-fetch requer configuração explícita do agente para trabalhar com proxy:

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(`Erro HTTP! status: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('Dados:', data);
    return data;
  } catch (error) {
    console.error('Fetch falhou:', error.message);
    throw error;
  }
}

fetchWithProxy();

O Got oferece uma funcionalidade mais rica fora da caixa (repetições automáticas, timeouts, tratamento de erros), enquanto o node-fetch é mais próximo da Fetch API padrão e é adequado para desenvolvedores familiarizados com JavaScript de navegador.

Conexão de proxy SOCKS5 através do socks-proxy-agent

SOCKS5 é um protocolo de proxy universal que opera em um nível mais baixo do que HTTP/HTTPS. Ele suporta qualquer tipo de tráfego, incluindo conexões UDP e WebSocket. Para trabalhar com SOCKS5 em Node.js, utiliza-se a biblioteca socks-proxy-agent.

Instalação dos pacotes necessários:

npm install socks-proxy-agent

Exemplo de uso de proxy SOCKS5 com várias bibliotecas:

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

// Configuração de proxy SOCKS5 com autenticação
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('Resposta SOCKS5:', data);
  });
}).on('error', (error) => {
  console.error('Solicitação SOCKS5 falhou:', error.message);
});

Uso de SOCKS5 com 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('Dados via SOCKS5:', response.data);
    return response.data;
  } catch (error) {
    console.error('Erro na solicitação SOCKS5:', error.message);
    throw error;
  }
}

fetchViaSocks5();

Proxies SOCKS5 são especialmente úteis para tarefas que requerem trabalho com protocolos não padrão ou quando é necessária máxima flexibilidade. Muitos provedores oferecem proxies móveis com suporte a SOCKS5, permitindo emular tráfego móvel para trabalhar com APIs móveis.

Implementação de rotação de proxy para distribuição de carga

Ao fazer scraping de grandes volumes de dados ou trabalhar com APIs que têm limites de solicitações de um único IP, é necessário usar rotação de proxies. Isso permite distribuir as solicitações entre vários servidores proxy e evitar bloqueios.

Exemplo de implementação de uma rotação simples de proxies:

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

class ProxyRotator {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
  }
  
  // Obter o próximo proxy de forma circular
  getNextProxy() {
    const proxy = this.proxyList[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Obter um proxy aleatório
  getRandomProxy() {
    const randomIndex = Math.floor(Math.random() * this.proxyList.length);
    return this.proxyList[randomIndex];
  }
  
  // Criar uma instância do Axios com o proxy atual
  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'
      }
    });
  }
}

// Lista de proxies
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);

// Uso da rotação
async function fetchWithRotation(url) {
  const axiosInstance = rotator.createAxiosInstance();
  
  try {
    const response = await axiosInstance.get(url);
    console.log('Sucesso com proxy');
    return response.data;
  } catch (error) {
    console.error('Solicitação falhou:', error.message);
    throw error;
  }
}

// Exemplo de scraping em massa com rotação
async function massiveParsing(urls) {
  const results = [];
  
  for (const url of urls) {
    try {
      const data = await fetchWithRotation(url);
      results.push({ url, success: true, data });
      
      // Atraso entre solicitações
      await new Promise(resolve => setTimeout(resolve, 1000));
    } catch (error) {
      results.push({ url, success: false, error: error.message });
    }
  }
  
  return results;
}

// Iniciar o scraping
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('Resultados do scraping:', results))
  .catch(error => console.error('Erro no scraping:', error));

Um exemplo mais avançado com monitoramento do estado do proxy e exclusão automática de proxies não funcionais:

class AdvancedProxyRotator {
  constructor(proxyList, maxFailures = 3) {
    this.proxyList = proxyList.map(url => ({
      url,
      failures: 0,
      active: true,
      lastUsed: null
    }));
    this.maxFailures = maxFailures;
    this.currentIndex = 0;
  }
  
  // Obter um proxy ativo
  getActiveProxy() {
    const activeProxies = this.proxyList.filter(p => p.active);
    
    if (activeProxies.length === 0) {
      throw new Error('Nenhum proxy ativo disponível');
    }
    
    // Encontrar o proxy que não foi usado há mais tempo
    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;
  }
  
  // Marcar proxy como bem-sucedido
  markSuccess(proxyUrl) {
    const proxy = this.proxyList.find(p => p.url === proxyUrl);
    if (proxy) {
      proxy.failures = 0;
    }
  }
  
  // Marcar proxy como falho
  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} desativado após ${proxy.failures} falhas`);
      }
    }
  }
  
  // Criar uma instância do Axios com rotação
  async createAxiosInstance() {
    const proxy = this.getActiveProxy();
    const agent = new HttpsProxyAgent(proxy.url);
    
    return {
      instance: axios.create({
        httpsAgent: agent,
        timeout: 10000
      }),
      proxyUrl: proxy.url
    };
  }
  
  // Obter estatísticas do proxy
  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(/\/\/.*@/, '//***@'), // Ocultar credenciais
        active: p.active,
        failures: p.failures
      }))
    };
  }
}

// Uso do rotador avançado
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;
  }
}

// Relatório periódico de estatísticas
setInterval(() => {
  console.log('Estatísticas do proxy:', advancedRotator.getStats());
}, 30000);

Esse sistema exclui automaticamente proxies não funcionais da rotação e distribui uniformemente a carga entre servidores ativos. Isso é crítico ao trabalhar com grandes volumes de dados.

Tratamento de erros e troca automática de proxy

Ao trabalhar com proxies, erros inevitavelmente ocorrem: timeouts, falhas de conexão, bloqueios por parte do servidor de destino. Um tratamento adequado de erros e a troca automática para outro proxy aumentam a confiabilidade da aplicação.

Exemplo de implementação de um sistema com repetições automáticas e troca de proxy:

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;
  }
  
  // Obter o próximo proxy
  getNextProxy() {
    const proxy = this.proxyList[this.currentProxyIndex];
    this.currentProxyIndex = (this.currentProxyIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Determinar o tipo de erro
  isRetryableError(error) {
    // Erros que devem resultar em repetição da solicitação
    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;
  }
  
  // Executar solicitação com repetições automáticas
  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(`Tentativa ${attempt}/${this.maxRetries} com proxy: ${proxyUrl.replace(/\/\/.*@/, '//***@')}`);
      const response = await axios.get(url, config);
      console.log(`Sucesso na tentativa ${attempt}`);
      return response.data;
    } catch (error) {
      console.error(`Tentativa ${attempt} falhou: ${error.message}`);
      
      // Se o limite de repetições foi alcançado
      if (attempt >= this.maxRetries) {
        console.error(`Máximo de repetições (${this.maxRetries}) alcançado para ${url}`);
        throw error;
      }
      
      // Se o erro não é recuperável
      if (!this.isRetryableError(error)) {
        console.error(`Erro não recuperável: ${error.message}`);
        throw error;
      }
      
      // Atraso exponencial antes da repetição
      const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
      console.log(`Aguardando ${delay}ms antes da repetição...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      
      // Repetição recursiva com o próximo proxy
      return this.request(url, options, attempt + 1);
    }
  }
  
  // Processamento em lote de URLs com tratamento de erros
  async batchRequest(urls, concurrency = 3) {
    const results = [];
    const queue = [...urls];
    const active = [];
    
    while (queue.length > 0 || active.length > 0) {
      // Iniciar novas tarefas até atingir o limite de paralelismo
      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);
      }
      
      // Aguardar a conclusão de pelo menos uma tarefa
      if (active.length > 0) {
        const result = await Promise.race(active);
        results.push(result);
      }
    }
    
    return results;
  }
}

// Uso
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);

// Solicitação única
client.request('https://api.example.com/data')
  .then(data => console.log('Dados:', data))
  .catch(error => console.error('Erro final:', error.message));

// Processamento em lote
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(`Concluído: ${successful} bem-sucedidos, ${failed} falharam`);
    console.log('Resultados:', results);
  });

Esta implementação inclui:

  • Troca automática para o próximo proxy em caso de erro
  • Atraso exponencial entre repetições (1s, 2s, 4s, 8s, 10s max)
  • Determinação do tipo de erro para decisão de repetição
  • Controle de paralelismo durante o processamento em lote
  • Registro detalhado para depuração

Melhores práticas e otimização de desempenho

Ao trabalhar com proxies em aplicações Node.js, é importante seguir as seguintes recomendações para garantir estabilidade e desempenho:

1. Gerenciamento de conexões

Reutilize agentes HTTP em vez de criar novos para cada solicitação. Isso reduz a sobrecarga na criação de conexões:

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

// Ruim: criação de agente para cada solicitação
async function badExample(url) {
  const agent = new HttpsProxyAgent(proxyUrl);
  return axios.get(url, { httpsAgent: agent });
}

// Bom: reutilização do agente
const agent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
  httpsAgent: agent,
  httpAgent: agent
});

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

2. Configuração de timeouts

Sempre defina timeouts razoáveis para evitar que a aplicação fique travada:

const axiosInstance = axios.create({
  httpsAgent: agent,
  timeout: 10000, // Timeout geral
  // Configuração detalhada de timeouts para Got
  // timeout: {
  //   lookup: 1000,    // Pesquisa DNS
  //   connect: 2000,   // Conexão com o proxy
  //   secureConnect: 2000, // Handshake SSL
  //   socket: 5000,    // Inatividade do socket
  //   response: 3000,  // Espera pelo primeiro byte da resposta
  //   send: 10000,     // Envio da solicitação
  //   request: 15000   // Toda a solicitação
  // }
});

3. Controle de paralelismo

Limite o número de solicitações simultâneas para evitar sobrecarga:

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

// Limitar a 5 solicitações simultâneas
const limit = pLimit(5);

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

4. Rotação de User-Agent

Combine a rotação de proxies com a rotação de User-Agent para maior anonimato:

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. Monitoramento e registro

Implemente um sistema de monitoramento para rastrear o desempenho dos proxies:

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();

// Wrapper para solicitações com monitoramento
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;
  }
}

// Relatório periódico
setInterval(() => {
  console.table(monitor.getReport());
}, 60000);

6. Escolha do tipo de proxy

Escolha o tipo de proxy com base na tarefa:

Tarefa Tipo recomendado Razão
Scraping em massa de dados públicos Proxies de datacenter Alta velocidade, baixo custo
Trabalho com redes sociais e plataformas com proteção Proxies residenciais IPs reais, baixo risco de bloqueio
Emulação de tráfego móvel Proxies móveis IPs de operadoras móveis
Trabalho com protocolos não padrão Proxies SOCKS5 Suporte a qualquer tráfego

Para tarefas que exigem um alto nível de anonimato e risco mínimo de bloqueios, recomenda-se usar proxies residenciais. Para scraping em alta velocidade de grandes volumes de dados, proxies de datacenter são adequados.

7. Segurança das credenciais

Nunca armazene credenciais de proxy no código. Use variáveis de ambiente:

// arquivo .env
PROXY_HOST=proxy-server.com
PROXY_PORT=8080
PROXY_USERNAME=your-username
PROXY_PASSWORD=your-password

// No código
require('dotenv').config();

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

// Ou para a lista de proxies
const proxyList = process.env.PROXY_LIST.split(',').map(proxy => proxy.trim());

Conclusão

A configuração de proxies em aplicações Node.js é uma habilidade importante para desenvolvedores que trabalham com scraping, automação e integração com APIs externas. Neste guia, abordamos todas as principais formas de trabalhar com proxies: desde a configuração básica através de módulos embutidos até técnicas avançadas com rotação, tratamento de erros e monitoramento.

Pontos-chave a serem lembrados:

  • Escolha a biblioteca para solicitações HTTP com base na tarefa: Axios para versatilidade, Got para projetos TypeScript, node-fetch para compatibilidade com a API do navegador
  • Use proxies SOCKS5 para trabalhar com protocolos não padrão e máxima flexibilidade
  • Implemente rotação de proxies para distribuição de carga e evitar bloqueios
  • Implemente um sistema de tratamento de erros com repetições automáticas e troca de proxies
  • Monitore o desempenho dos proxies e exclua automaticamente os não funcionais
  • Reutilize agentes HTTP e configure timeouts razoáveis
  • Armazene credenciais em variáveis de ambiente, não no código

Ao escolher proxies para suas aplicações Node.js, considere a especificidade da tarefa. Para scraping de plataformas protegidas e trabalho com APIs sensíveis à reputação do IP, recomendamos o uso de proxies residenciais — eles oferecem um alto nível de anonimato e risco mínimo de bloqueios devido ao uso de endereços IP reais de usuários domésticos.

```