Socks5Proxy

Configurazione proxy in Node.js, collegamento di proxy HTTP e SOCKS5 a fetch e https

Questa guida spiega come connettere i proxy HTTP di Socks5Proxy con ProxyAgent di undici e i proxy SOCKS5 con socks-proxy-agent in Node.js 18+, e come ricevere e ruotare le liste via API.

Cosa serve per usare un proxy in Node.js?

Il fetch integrato in Node.js funziona con la libreria undici e di default non legge le impostazioni del proxy. Quindi, per il proxy HTTP si passa ProxyAgent di undici come dispatcher, mentre per il proxy SOCKS5 si passa socks-proxy-agent come agente al modulo https di Node.

L'esempio usa IP 198.51.100.23, porta HTTP 8000, porta SOCKS5 1080, username spx_user e password spx_pass. Tutto il codice è in formato modulo ES (.mjs).

npm install undici socks-proxy-agent

Come si connette un proxy HTTP a fetch?

Inserisci l'indirizzo proxy in ProxyAgent e il nome utente e la password nell'opzione token come valore di autenticazione Basic. Passalo come dispatcher a fetch importato da undici e la richiesta passerà attraverso il proxy. Gli indirizzi HTTPS vengono trasmessi crittografati con il metodo CONNECT.

Riutilizzando lo stesso ProxyAgent per più richieste, le connessioni vengono riusate, accelerando il processo. Crea un agent per ogni proxy e alternali.

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

Come si connette un proxy SOCKS5?

socks-proxy-agent è un agente utilizzato con i moduli http e https di Node. Utilizzando l'indirizzo socks5h, la risoluzione del nome di dominio viene gestita dal proxy. L'esempio seguente passa l'agente a https.get e raccoglie e stampa il corpo della risposta.

Anche le librerie che operano sul modulo http, come axios, possono utilizzare SOCKS5 passando lo stesso agente a httpAgent e httpsAgent.

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

Come ottenere e ruotare una lista via API?

All'inizio, ricevi l'elenco via API e crei un agente per ogni proxy, utilizzando l'agente successivo per ogni richiesta. Il codice seguente scarica l'elenco HTTP in formato ip:port:user:pass, crea un array di ProxyAgent e riprova con il proxy successivo in caso di errore.

Aggiungi sempre un timeout con AbortSignal.timeout alle richieste. Le richieste senza risposta rallentano l'intero processo.

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

Come cambia il codice quando si usa l'autorizzazione IP?

Se registri l'IPv4 del server che esegue Node.js nel dashboard, puoi usare ProxyAgent senza il token, inserendo solo l'indirizzo. Anche SOCKS5 può essere utilizzato senza username e password, ad esempio socks5h://198.51.100.23:1080. Questo rende più facile distribuire il codice su più server senza dover memorizzare le password nelle variabili d'ambiente o nel codice.

Come ci si connette utilizzando axios?

axios opera sui moduli http e https di Node, quindi è possibile passare un agente per utilizzare il proxy. Per SOCKS5, utilizzare socks-proxy-agent per httpAgent e httpsAgent e impostare l'opzione proxy di axios su false per evitare sovrapposizioni.

È possibile specificare host, port e auth nell'opzione proxy di axios per un proxy HTTP, ma per indirizzi HTTPS è più stabile utilizzare un agente. Il pacchetto https-proxy-agent permette di connettere un proxy HTTP con la stessa struttura.

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

Cosa bisogna considerare quando si inviano più richieste contemporaneamente?

Se avvii migliaia di richieste contemporaneamente con Promise.all, si apriranno troppe connessioni, sovraccaricando sia il proxy che il sito di destinazione. Imposta una coda di lavoro per limitare il numero di richieste simultanee. Puoi creare una piccola funzione o usare un pacchetto come p-limit.

Distribuire uniformemente le connessioni simultanee tra i proxy evita che le richieste si concentrino su un singolo IP. I piani condivisi includono 500 connessioni simultanee, quindi assicurati di rimanere entro questo limite.

È possibile applicare il proxy a tutte le richieste tramite variabili d'ambiente?

EnvHttpProxyAgent di undici legge le variabili d'ambiente HTTP_PROXY, HTTPS_PROXY e NO_PROXY per impostare il proxy. Registrandolo con setGlobalDispatcher, tutte le fetch di quel processo passeranno attraverso il proxy. È utile quando più librerie utilizzano fetch internamente.

Le impostazioni globali utilizzano lo stesso IP per tutte le richieste, quindi sono più adatte per strumenti o test che richiedono l'accesso da un unico paese rispetto alle raccolte che richiedono la divisione degli IP. Se hai bisogno di rotazione, passa il dispatcher per ogni richiesta come visto prima.

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

Come risolvere i problemi più comuni?

Se sembra che il dispatcher passato a fetch integrato in Node.js venga ignorato, verifica se fetch è stato importato dal pacchetto undici. Se le versioni di fetch integrato e undici installato sono diverse, l'agente potrebbe non corrispondere, quindi il metodo più sicuro è importare sia fetch che ProxyAgent dallo stesso pacchetto.

La risposta 407 indica credenziali errate. Verifica che dopo 'Basic' nel token ci sia il valore base64 di username:password. ECONNREFUSED spesso indica una porta errata. Usa la porta HTTP per gli agent HTTP e la porta SOCKS5 per gli agent SOCKS.

  • fetch e ProxyAgent sono nello stesso pacchetto undici
  • 407: verifica token e IP registrato
  • ECONNREFUSED: distinzione tra porta HTTP e SOCKS5
  • Limite di tempo per tutte le richieste
Configurazione proxy in Node.js, collegamento di agenti undici e SOCKS5 | Socks5Proxy