Socks5Proxy

Configuration du proxy dans Node.js, connexion des proxies HTTP et SOCKS5 à fetch et https

Ce guide explique comment connecter les proxies HTTP de Socks5Proxy avec ProxyAgent d'undici et les proxies SOCKS5 avec socks-proxy-agent dans Node.js 18+, ainsi que comment récupérer et faire tourner une liste via l'API.

De quoi avez-vous besoin pour utiliser un proxy dans Node.js?

Le fetch intégré dans Node.js fonctionne avec la bibliothèque undici et ne lit pas les paramètres de proxy par défaut. Donc, pour le proxy HTTP, vous passez ProxyAgent d'undici comme dispatcher, et pour le proxy SOCKS5, vous passez socks-proxy-agent comme agent au module https de Node.

L'exemple utilise l'IP 198.51.100.23, port HTTP 8000, port SOCKS5 1080, identifiant spx_user et mot de passe spx_pass. Tous les codes sont au format module ES (.mjs).

npm install undici socks-proxy-agent

Comment connecter un proxy HTTP à fetch ?

Ajoutez l'adresse du proxy à ProxyAgent, et l'identifiant et le mot de passe dans l'option token comme valeur d'authentification Basic. Passez-le comme dispatcher à fetch importé d'undici, et la requête passera par le proxy. Les adresses HTTPS sont transmises chiffrées via la méthode CONNECT.

Réutiliser le même ProxyAgent pour plusieurs requêtes réutilise les connexions, ce qui est plus rapide. Créez un agent par proxy et utilisez-les à tour de rôle.

import { fetch, ProxyAgent } from "undici";

const agent = new ProxyAgent({
  uri: "http://198.51.100.23:8000",
  token: "Basic " + Buffer.from("spx_user:spx_pass").toString("base64"),
});

const res = await fetch("https://api.ipify.org?format=json", { dispatcher: agent });
console.log(res.status, await res.json()); // "ip" should be the proxy IP

Comment se connecter à un proxy SOCKS5 ?

socks-proxy-agent est un agent utilisé avec les modules http et https de Node. Utilisez socks5h pour que le serveur proxy résolve les noms de domaine. L'exemple ci-dessous passe l'agent à https.get et collecte le corps de la réponse pour l'afficher.

Pour les librairies basées sur le module http (comme axios), passez le même agent SOCKS dans httpAgent et httpsAgent pour router les requêtes via SOCKS5.

import https from "node:https";
import { SocksProxyAgent } from "socks-proxy-agent";

const agent = new SocksProxyAgent("socks5h://spx_user:spx_pass@198.51.100.23:1080");

https.get("https://api.ipify.org?format=json", { agent }, (res) => {
  let body = "";
  res.on("data", (chunk) => (body += chunk));
  res.on("end", () => console.log(res.statusCode, body));
}).on("error", (err) => console.error("request failed:", err.message));

Comment obtenir et faire tourner une liste via l'API ?

Au démarrage, récupérez la liste via l'API et créez un agent pour chaque proxy, puis utilisez l'agent suivant pour chaque requête. Le code ci-dessous récupère la liste HTTP au format ip:port:user:pass, crée un tableau de ProxyAgent, et réessaie avec le proxy suivant en cas d'échec.

Ajoutez toujours une limite de temps avec AbortSignal.timeout dans vos requêtes. Les requêtes sans réponse peuvent ralentir l'ensemble du processus.

import { fetch, ProxyAgent } from "undici";

const API = "https://socks5proxy.io/api/v1";
const KEY = "YOUR_API_KEY";

const text = await (await fetch(API + "/proxies/download?format=ip:port:user:pass&protocol=http", {
  headers: { Authorization: "Bearer " + KEY },
})).text();

const agents = text.trim().split("\n").map((line) => {
  const [ip, port, user, pass] = line.trim().split(":");
  return new ProxyAgent({
    uri: "http://" + ip + ":" + port,
    token: "Basic " + Buffer.from(user + ":" + pass).toString("base64"),
  });
});

let i = 0;
async function get(url, tries = 3) {
  for (let t = 0; t < tries; t++) {
    const dispatcher = agents[i++ % agents.length];
    try {
      const res = await fetch(url, { dispatcher, signal: AbortSignal.timeout(20000) });
      if (res.ok) return await res.text();
    } catch {
      // try the next proxy
    }
  }
  return null;
}

console.log((await get("https://example.com/"))?.length);

Comment le code change-t-il avec l'autorisation IP ?

Si vous enregistrez l'IPv4 du serveur exécutant Node.js dans le tableau de bord, vous pouvez simplement utiliser l'adresse sans le token dans ProxyAgent. Pour SOCKS5, vous pouvez utiliser socks5h://198.51.100.23:1080 sans nom d'utilisateur ni mot de passe. Cela facilite le déploiement sur plusieurs serveurs sans avoir à stocker les mots de passe dans les variables d'environnement ou le code.

Comment configurer axios pour utiliser un proxy ?

axios fonctionne sur les modules http/https de Node. Pour SOCKS5 : utilisez socks-proxy-agent comme httpAgent/httpsAgent, et désactivez l'option proxy d'axios pour éviter les conflits.

Pour un proxy HTTP, vous pouvez utiliser l'option proxy d'axios avec host, port, auth, mais pour les adresses HTTPS, l'utilisation d'un agent est plus stable. Le package https-proxy-agent permet de connecter un proxy HTTP de la même manière.

import axios from "axios";
import { SocksProxyAgent } from "socks-proxy-agent";

const agent = new SocksProxyAgent("socks5h://spx_user:spx_pass@198.51.100.23:1080");
const client = axios.create({ httpAgent: agent, httpsAgent: agent, proxy: false, timeout: 20000 });

const { data } = await client.get("https://api.ipify.org?format=json");
console.log(data);

Que faut-il prendre en compte lors de l'envoi de plusieurs requêtes simultanément ?

Si vous démarrez des milliers de requêtes avec Promise.all, trop de connexions seront ouvertes, ce qui surchargera le proxy et le site cible. Définissez un nombre de requêtes simultanées et utilisez une file d'attente pour les exécuter. Vous pouvez créer une petite fonction ou utiliser un package comme p-limit.

Répartissez uniformément les connexions simultanées entre proxies pour éviter la surcharge d'une seule IP. Les plans partagés incluent 500 connexions simultanées - restez dans cette limite.

Puis-je appliquer un proxy à toutes les requêtes via des variables d'environnement ?

EnvHttpProxyAgent de undici lit les variables d'environnement HTTP_PROXY, HTTPS_PROXY et NO_PROXY pour définir le proxy. Enregistrez-le avec setGlobalDispatcher, et toutes les requêtes fetch de ce processus passeront par le proxy. C'est pratique pour appliquer le proxy à plusieurs bibliothèques qui utilisent fetch en interne.

Les paramètres globaux utilisent la même IP pour toutes les requêtes, ce qui convient mieux aux outils ou tests nécessitant une connexion depuis un seul pays plutôt qu'aux collectes nécessitant une rotation d'IP. Pour une rotation, passez un dispatcher à chaque requête comme vu précédemment.

// HTTPS_PROXY=http://spx_user:spx_pass@198.51.100.23:8000 node app.mjs
import { EnvHttpProxyAgent, setGlobalDispatcher, fetch } from "undici";

setGlobalDispatcher(new EnvHttpProxyAgent());
const res = await fetch("https://api.ipify.org");
console.log(await res.text());

Comment résoudre les problèmes fréquents ?

Si vous passez un dispatcher à fetch intégré de Node.js mais qu'il semble être ignoré, vérifiez si vous avez également importé fetch depuis le package undici. Si les versions de fetch intégré et d'undici installé diffèrent, l'agent peut ne pas correspondre, donc la méthode la plus sûre est d'importer fetch et ProxyAgent depuis le même package.

Une réponse 407 indique que les informations d'authentification sont incorrectes. Vérifiez que la valeur 'token' contient bien l'ID:mot de passe encodé en base64 après 'Basic'. ECONNREFUSED signifie souvent que le port est incorrect. Utilisez le port HTTP pour les agents HTTP et le port SOCKS5 pour les agents SOCKS.

  • fetch et ProxyAgent sont dans le même package undici
  • 407 : Vérifiez la valeur 'token' et l'IP enregistrée
  • ECONNREFUSED : Distinction entre port HTTP et port SOCKS5
  • Limite de temps pour toutes les requêtes
Configuration du proxy dans Node.js, connexion des agents undici et SOCKS5 | Socks5Proxy