Retour au blog

Configuration de proxy dans les applications Node.js : guide complet avec des exemples de code

Guide détaillé sur l'intégration de proxy dans Node.js : de la configuration de base aux techniques avancées de rotation d'IP et de gestion des erreurs.

📅14 février 2026
```html

Lors du développement d'applications Node.js pour le scraping, l'automatisation ou le travail avec des API, il est souvent nécessaire d'utiliser des serveurs proxy. Cela permet de contourner les restrictions géographiques, de répartir la charge et d'éviter les blocages par IP. Dans ce guide, nous examinerons tous les moyens de configurer un proxy dans Node.js — des techniques de base aux techniques avancées avec rotation et gestion des erreurs.

Concepts de base du travail avec des proxy dans Node.js

Un serveur proxy dans Node.js fonctionne comme un intermédiaire entre votre application et le serveur cible. Lorsque vous envoyez une requête HTTP via un proxy, votre application se connecte d'abord au serveur proxy, qui redirige ensuite la requête vers l'adresse finale. Cela permet de masquer l'adresse IP réelle de votre serveur et d'utiliser l'adresse IP du proxy.

Dans Node.js, il existe plusieurs façons de travailler avec des proxy en fonction de la bibliothèque utilisée pour les requêtes HTTP. Les options les plus populaires sont :

  • Modules intégrés http/https — fonctionnalité de base sans dépendances supplémentaires
  • Axios — bibliothèque populaire avec une API conviviale et un support des promesses
  • Got — alternative moderne avec support TypeScript
  • node-fetch — implémentation de l'API Fetch pour Node.js
  • request — bibliothèque obsolète mais encore utilisée (non recommandée pour les nouveaux projets)

Les serveurs proxy prennent en charge différents protocoles. Pour travailler avec Node.js, on utilise le plus souvent :

Protocole Description Utilisation
HTTP Protocole de base pour les connexions non sécurisées Scraping, travail avec des API sans SSL
HTTPS Proxy avec support de chiffrement SSL/TLS Connexions sécurisées, travail avec des API protégées
SOCKS5 Protocole universel pour tout type de trafic WebSocket, UDP, scénarios complexes

Pour les tâches de scraping et d'automatisation, les développeurs utilisent souvent des proxies résidentiels, car ils possèdent de vraies adresses IP d'utilisateurs domestiques et sont moins susceptibles d'être bloqués par les sites cibles.

Configuration de proxy via le module http/https intégré

Node.js fournit des modules intégrés http et https pour travailler avec des requêtes HTTP. Pour se connecter à un proxy, vous pouvez utiliser la bibliothèque http-proxy-agent ou https-proxy-agent.

Commencez par installer les paquets nécessaires :

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

Exemple d'utilisation d'un proxy HTTP avec le module intégré :

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

// Paramètres du proxy
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpProxyAgent(proxyUrl);

// Options de la requête
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'
  }
};

// Exécution de la requête
const req = http.request(options, (res) => {
  let data = '';
  
  res.on('data', (chunk) => {
    data += chunk;
  });
  
  res.on('end', () => {
    console.log('Réponse :', data);
  });
});

req.on('error', (error) => {
  console.error('Échec de la requête :', error.message);
});

req.end();

Pour les connexions HTTPS, utilisez 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('Réponse sécurisée :', data);
  });
}).on('error', (error) => {
  console.error('Échec de la requête HTTPS :', error.message);
});

Cette approche offre un contrôle maximal sur les requêtes, mais nécessite plus de code pour gérer les promesses et les erreurs. Pour la plupart des tâches, il est plus pratique d'utiliser des bibliothèques spécialisées.

Travail avec des proxy dans la bibliothèque Axios

Axios est l'une des bibliothèques les plus populaires pour les requêtes HTTP dans Node.js. Elle fournit une API conviviale pour configurer des proxy et gère automatiquement les promesses.

Installation d'Axios :

npm install axios

La configuration de base d'un proxy dans Axios se présente comme suit :

const axios = require('axios');

// Méthode 1 : Configuration du proxy dans la configuration de la requête
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('Données :', response.data);
})
.catch(error => {
  console.error('Erreur :', error.message);
});

Pour réutiliser plusieurs fois les mêmes paramètres de proxy, il est pratique de créer une instance d'Axios avec une configuration prédéfinie :

const axios = require('axios');

// Création d'une instance avec des paramètres 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'
  }
});

// Utilisation de l'instance
async function fetchData() {
  try {
    const response = await axiosWithProxy.get('https://api.example.com/data');
    console.log('Réponse :', response.data);
    return response.data;
  } catch (error) {
    console.error('Échec de la requête :', error.message);
    throw error;
  }
}

fetchData();

Pour travailler avec des proxy HTTPS via la méthode CONNECT, vous pouvez utiliser des agents supplémentaires :

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

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

Axios gère automatiquement les redirections et prend en charge les intercepteurs pour la journalisation et la gestion des erreurs, ce qui en fait un excellent choix pour les projets utilisant activement des proxies.

Configuration de proxy dans got et node-fetch

Got est une alternative moderne à Axios avec un excellent support TypeScript et des capacités avancées de gestion des erreurs. Node-fetch implémente l'API Fetch standard pour Node.js.

Travail avec des proxy dans Got

Installation de Got et des agents nécessaires :

npm install got https-proxy-agent

Exemple de configuration d'un proxy dans 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)
};

// Création d'une instance Got avec proxy
const gotWithProxy = got.extend({
  agent: agent,
  timeout: {
    request: 10000
  },
  retry: {
    limit: 3,
    methods: ['GET', 'POST']
  }
});

// Utilisation
async function fetchWithGot() {
  try {
    const response = await gotWithProxy('https://api.example.com/data');
    console.log('Réponse :', JSON.parse(response.body));
  } catch (error) {
    console.error('Échec de la requête Got :', error.message);
  }
}

fetchWithGot();

Travail avec des proxy dans node-fetch

Node-fetch nécessite une configuration explicite de l'agent pour travailler avec des 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(`Erreur HTTP ! statut : ${response.status}`);
    }
    
    const data = await response.json();
    console.log('Données :', data);
    return data;
  } catch (error) {
    console.error('Échec du fetch :', error.message);
    throw error;
  }
}

fetchWithProxy();

Got fournit une fonctionnalité plus riche dès le départ (retries automatiques, timeouts, gestion des erreurs), tandis que node-fetch est plus proche de l'API Fetch standard et convient aux développeurs familiers avec JavaScript dans le navigateur.

Connexion à un proxy SOCKS5 via socks-proxy-agent

SOCKS5 est un protocole proxy universel qui fonctionne à un niveau plus bas que HTTP/HTTPS. Il prend en charge tout type de trafic, y compris les connexions UDP et WebSocket. Pour travailler avec SOCKS5 dans Node.js, on utilise la bibliothèque socks-proxy-agent.

Installation des paquets nécessaires :

npm install socks-proxy-agent

Exemple d'utilisation d'un proxy SOCKS5 avec différentes bibliothèques :

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

// Configuration du proxy SOCKS5 avec authentification
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('Réponse SOCKS5 :', data);
  });
}).on('error', (error) => {
  console.error('Échec de la requête SOCKS5 :', error.message);
});

Utilisation de SOCKS5 avec 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('Données via SOCKS5 :', response.data);
    return response.data;
  } catch (error) {
    console.error('Erreur de requête SOCKS5 :', error.message);
    throw error;
  }
}

fetchViaSocks5();

Les proxies SOCKS5 sont particulièrement utiles pour les tâches nécessitant de travailler avec des protocoles non standards ou lorsque la flexibilité maximale est requise. De nombreux fournisseurs proposent des proxies mobiles avec support SOCKS5, ce qui permet d'émuler le trafic mobile pour travailler avec des API mobiles.

Mise en œuvre de la rotation des proxy pour répartir la charge

Lors du scraping de grandes quantités de données ou du travail avec des API ayant des limites sur le nombre de requêtes par IP, il est nécessaire d'utiliser la rotation des proxy. Cela permet de répartir les requêtes entre plusieurs serveurs proxy et d'éviter les blocages.

Exemple de mise en œuvre d'une simple rotation de proxy :

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

class ProxyRotator {
  constructor(proxyList) {
    this.proxyList = proxyList;
    this.currentIndex = 0;
  }
  
  // Obtenir le prochain proxy de manière circulaire
  getNextProxy() {
    const proxy = this.proxyList[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Obtenir un proxy aléatoire
  getRandomProxy() {
    const randomIndex = Math.floor(Math.random() * this.proxyList.length);
    return this.proxyList[randomIndex];
  }
  
  // Créer une instance Axios avec le proxy actuel
  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'
      }
    });
  }
}

// Liste des 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);

// Utilisation de la rotation
async function fetchWithRotation(url) {
  const axiosInstance = rotator.createAxiosInstance();
  
  try {
    const response = await axiosInstance.get(url);
    console.log('Succès avec le proxy');
    return response.data;
  } catch (error) {
    console.error('Échec de la requête :', error.message);
    throw error;
  }
}

// Exemple de scraping massif avec rotation
async function massiveParsing(urls) {
  const results = [];
  
  for (const url of urls) {
    try {
      const data = await fetchWithRotation(url);
      results.push({ url, success: true, data });
      
      // Délai entre les requêtes
      await new Promise(resolve => setTimeout(resolve, 1000));
    } catch (error) {
      results.push({ url, success: false, error: error.message });
    }
  }
  
  return results;
}

// Lancer le 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('Résultats du scraping :', results))
  .catch(error => console.error('Erreur de scraping :', error));

Un exemple plus avancé avec suivi de l'état des proxies et exclusion automatique des non fonctionnels :

class AdvancedProxyRotator {
  constructor(proxyList, maxFailures = 3) {
    this.proxyList = proxyList.map(url => ({
      url,
      failures: 0,
      active: true,
      lastUsed: null
    }));
    this.maxFailures = maxFailures;
    this.currentIndex = 0;
  }
  
  // Obtenir un proxy actif
  getActiveProxy() {
    const activeProxies = this.proxyList.filter(p => p.active);
    
    if (activeProxies.length === 0) {
      throw new Error('Aucun proxy actif disponible');
    }
    
    // Trouver le proxy qui n'a pas été utilisé depuis le plus longtemps
    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;
  }
  
  // Marquer un proxy comme réussi
  markSuccess(proxyUrl) {
    const proxy = this.proxyList.find(p => p.url === proxyUrl);
    if (proxy) {
      proxy.failures = 0;
    }
  }
  
  // Marquer un proxy comme échoué
  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} désactivé après ${proxy.failures} échecs`);
      }
    }
  }
  
  // Créer une instance Axios avec rotation
  async createAxiosInstance() {
    const proxy = this.getActiveProxy();
    const agent = new HttpsProxyAgent(proxy.url);
    
    return {
      instance: axios.create({
        httpsAgent: agent,
        timeout: 10000
      }),
      proxyUrl: proxy.url
    };
  }
  
  // Obtenir des statistiques sur les proxies
  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(/\/\/.*@/, '//***@'), // Masquer les identifiants
        active: p.active,
        failures: p.failures
      }))
    };
  }
}

// Utilisation du rotateur avancé
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;
  }
}

// Rapport périodique des statistiques
setInterval(() => {
  console.log('Statistiques des proxies :', advancedRotator.getStats());
}, 30000);

Ce système exclut automatiquement les proxies non fonctionnels de la rotation et répartit uniformément la charge entre les serveurs actifs. Cela est crucial lors du traitement de grandes quantités de données.

Gestion des erreurs et basculement automatique des proxy

Lors du travail avec des proxies, des erreurs surviennent inévitablement : délais d'attente, refus de connexion, blocages par le serveur cible. Une bonne gestion des erreurs et un basculement automatique vers un autre proxy augmentent la fiabilité de l'application.

Exemple de mise en œuvre d'un système avec des répétitions automatiques et un basculement 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;
  }
  
  // Obtenir le prochain proxy
  getNextProxy() {
    const proxy = this.proxyList[this.currentProxyIndex];
    this.currentProxyIndex = (this.currentProxyIndex + 1) % this.proxyList.length;
    return proxy;
  }
  
  // Déterminer le type d'erreur
  isRetryableError(error) {
    // Erreurs pour lesquelles il vaut la peine de répéter la requête
    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;
  }
  
  // Exécuter une requête avec des répétitions automatiques
  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(`Tentative ${attempt}/${this.maxRetries} avec le proxy : ${proxyUrl.replace(/\/\/.*@/, '//***@')}`);
      const response = await axios.get(url, config);
      console.log(`Succès à la tentative ${attempt}`);
      return response.data;
    } catch (error) {
      console.error(`Échec de la tentative ${attempt} : ${error.message}`);
      
      // Si la limite de répétitions est atteinte
      if (attempt >= this.maxRetries) {
        console.error(`Limite de répétitions (${this.maxRetries}) atteinte pour ${url}`);
        throw error;
      }
      
      // Si l'erreur n'est pas répétable
      if (!this.isRetryableError(error)) {
        console.error(`Erreur non répétable : ${error.message}`);
        throw error;
      }
      
      // Délai exponentiel avant de répéter
      const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
      console.log(`Attente de ${delay}ms avant de réessayer...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      
      // Répétition récursive avec le prochain proxy
      return this.request(url, options, attempt + 1);
    }
  }
  
  // Traitement par lots d'URL avec gestion des erreurs
  async batchRequest(urls, concurrency = 3) {
    const results = [];
    const queue = [...urls];
    const active = [];
    
    while (queue.length > 0 || active.length > 0) {
      // Lancer de nouvelles tâches jusqu'à atteindre la limite de parallélisme
      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);
      }
      
      // Attendre la fin d'au moins une tâche
      if (active.length > 0) {
        const result = await Promise.race(active);
        results.push(result);
      }
    }
    
    return results;
  }
}

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

// Requête unique
client.request('https://api.example.com/data')
  .then(data => console.log('Données :', data))
  .catch(error => console.error('Erreur finale :', error.message));

// Traitement par lots
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(`Terminé : ${successful} réussi, ${failed} échoué`);
    console.log('Résultats :', results);
  });

Cette implémentation comprend :

  • Basculement automatique vers le prochain proxy en cas d'erreur
  • Délai exponentiel entre les répétitions (1s, 2s, 4s, 8s, 10s max)
  • Détermination du type d'erreur pour prendre une décision de répétition
  • Contrôle du parallélisme lors du traitement par lots
  • Journalisation détaillée pour le débogage

Meilleures pratiques et optimisation des performances

Lors du travail avec des proxies dans les applications Node.js, il est conseillé de suivre les recommandations suivantes pour assurer la stabilité et les performances :

1. Gestion des connexions

Réutilisez les agents HTTP au lieu de créer de nouveaux pour chaque requête. Cela réduit le surcoût lié à l'établissement de connexions :

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

// Mauvais : création d'un agent pour chaque requête
async function badExample(url) {
  const agent = new HttpsProxyAgent(proxyUrl);
  return axios.get(url, { httpsAgent: agent });
}

// Bon : réutilisation de l'agent
const agent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
  httpsAgent: agent,
  httpAgent: agent
});

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

2. Configuration des délais d'attente

Toujours définir des délais d'attente raisonnables pour éviter que l'application ne se bloque :

const axiosInstance = axios.create({
  httpsAgent: agent,
  timeout: 10000, // Délai d'attente global
  // Configuration détaillée des délais d'attente pour Got
  // timeout: {
  //   lookup: 1000,    // Recherche DNS
  //   connect: 2000,   // Connexion au proxy
  //   secureConnect: 2000, // Négociation SSL
  //   socket: 5000,    // Inactivité du socket
  //   response: 3000,  // Attente du premier octet de réponse
  //   send: 10000,     // Envoi de la requête
  //   request: 15000   // Toute la requête
  // }
});

3. Contrôle du parallélisme

Limitez le nombre de requêtes simultanées pour éviter la surcharge :

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

// Limite à 5 requêtes simultanées
const limit = pLimit(5);

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

4. Rotation des User-Agent

Combinez la rotation des proxies avec la rotation des User-Agent pour plus d'anonymat :

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. Surveillance et journalisation

Implémentez un système de surveillance pour suivre les performances des 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(/\/\/.*@/, '//***@'), // Masquer les identifiants
        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();

// Enveloppe pour les requêtes avec surveillance
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;
  }
}

// Rapport périodique
setInterval(() => {
  console.table(monitor.getReport());
}, 60000);

6. Choix du type de proxy

Choisissez le type de proxy en fonction de la tâche :

Tâche Type recommandé Raison
Scraping massif de données publiques Proxy de centre de données Haute vitesse, faible coût
Travail avec des réseaux sociaux et des plateformes protégées Proxies résidentiels IP réelles, faible risque de blocage
Émulation de trafic mobile Proxies mobiles IP des opérateurs mobiles
Travail avec des protocoles non standards Proxies SOCKS5 Support de tout le trafic

Pour les tâches nécessitant un haut niveau d'anonymat et un risque minimal de blocage, il est recommandé d'utiliser des proxies résidentiels. Pour le scraping rapide de grandes quantités de données, des proxies de centre de données conviennent.

7. Sécurité des identifiants

Ne stockez jamais les identifiants de proxy dans le code. Utilisez des variables d'environnement :

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

// Dans le code
require('dotenv').config();

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

// Ou pour une liste de proxies
const proxyList = process.env.PROXY_LIST.split(',').map(proxy => proxy.trim());

Conclusion

La configuration de proxy dans les applications Node.js est une compétence importante pour les développeurs travaillant avec le scraping, l'automatisation et l'intégration avec des API externes. Dans ce guide, nous avons examiné toutes les principales façons de travailler avec des proxies : de la configuration de base via les modules intégrés aux techniques avancées de rotation, de gestion des erreurs et de surveillance.

Points clés à retenir :

  • Choisissez une bibliothèque pour les requêtes HTTP en fonction de la tâche : Axios pour la polyvalence, Got pour les projets TypeScript, node-fetch pour la compatibilité avec l'API du navigateur
  • Utilisez des proxies SOCKS5 pour travailler avec des protocoles non standards et une flexibilité maximale
  • Implémentez la rotation des proxies pour répartir la charge et éviter les blocages
  • Mettez en place un système de gestion des erreurs avec des répétitions automatiques et un basculement de proxy
  • Surveillez les performances des proxies et excluez automatiquement les non fonctionnels
  • Réutilisez les agents HTTP et configurez des délais d'attente raisonnables
  • Stockez les identifiants dans des variables d'environnement, pas dans le code

Lors du choix de proxies pour vos applications Node.js, tenez compte de la spécificité de la tâche. Pour le scraping de plateformes protégées et le travail avec des API sensibles à la réputation des IP, nous recommandons d'utiliser des proxies résidentiels — ils offrent un haut niveau d'anonymat et un risque minimal de blocage grâce à l'utilisation de vraies adresses IP d'utilisateurs domestiques.

```