Configuração de proxy no Node.js: conectar proxies HTTP e SOCKS5 ao fetch e https
Este guia explica como conectar proxies HTTP da Socks5Proxy via undici ProxyAgent e proxies SOCKS5 via socks-proxy-agent no Node.js 18+, além de código para rotacionar IPs usando a API.
O que é necessário para usar proxy no Node.js?
O fetch nativo do Node.js usa a biblioteca undici e não lê configurações de proxy por padrão. Para HTTP, use ProxyAgent do undici como dispatcher. Para SOCKS5, use socks-proxy-agent como agente no módulo https do Node.
O exemplo usa IP 198.51.100.23, porta HTTP 8000, porta SOCKS5 1080, nome de usuário spx_user e senha spx_pass. Todo o código está no formato de módulo ES (.mjs).
npm install undici socks-proxy-agentComo configurar proxy HTTP com fetch?
Passe o endereço do proxy no ProxyAgent e credenciais como token Basic. Passe o dispatcher para o fetch do undici, e a requisição usará o proxy. URLs HTTPS são passadas criptografadas via CONNECT.
Reutilizar o mesmo ProxyAgent para várias solicitações acelera as conexões. Crie um agente por proxy e use-os alternadamente.
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 IPComo conectar um proxy SOCKS5?
socks-proxy-agent é um agente para uso com os módulos http e https do Node. Use socks5h no endereço para resolver DNS no proxy. O exemplo abaixo passa o agente para https.get e exibe o corpo da resposta.
Bibliotecas baseadas no módulo http (como axios) podem usar SOCKS5 definindo o mesmo agent em 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));Como obter e rotacionar lista via API?
Ao iniciar, obtenha a lista via API e crie um agente para cada proxy, usando o próximo agente a cada requisição. O código abaixo obtém a lista HTTP no formato ip:port:user:pass, cria um array de ProxyAgent e, em caso de falha, tenta novamente com o próximo proxy.
Adicione um timeout com AbortSignal.timeout em cada solicitação. Solicitações sem resposta podem retardar todo o 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);Como muda o código com autorização por IP?
Registre o IPv4 do servidor Node.js no dashboard para usar o ProxyAgent sem token, apenas com o endereço. O SOCKS5 também funciona sem credenciais, como socks5h://198.51.100.23:1080. Isso facilita a implantação em vários servidores sem expor senhas em variáveis de ambiente ou código.
Como configurar conexão com axios?
O axios opera sobre os módulos http/https do Node. Para SOCKS5, use socks-proxy-agent em httpAgent/httpsAgent e defina proxy: false para evitar conflitos.
O proxy HTTP pode ser configurado com a opção proxy em axios, inserindo host, port e auth, mas para endereços HTTPS, usar um agente é mais estável. O pacote https-proxy-agent permite conectar proxies HTTP na mesma estrutura.
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);O que devo considerar ao enviar várias solicitações simultaneamente?
Enviar milhares de requisições de uma vez com Promise.all sobrecarrega proxies e sites. Limite o número de conexões simultâneas com uma fila de tarefas, usando desde funções simples até pacotes como p-limit.
Distribuir conexões simultâneas igualmente entre proxies evita sobrecarga em um único IP. Planos compartilhados incluem 500 conexões simultâneas - ajuste o total de requisições para esse limite.
Posso aplicar proxy a todas as solicitações usando variáveis de ambiente?
EnvHttpProxyAgent do undici lê variáveis HTTP_PROXY, HTTPS_PROXY e NO_PROXY. setGlobalDispatcher aplica o proxy a todos os fetch do processo, útil quando várias bibliotecas usam fetch internamente.
Configurações globais usam o mesmo IP para todas as solicitações, sendo mais adequadas para ferramentas ou testes que precisam acessar de um único país, em vez de coletas que precisam dividir IPs. Se precisar de rotação, passe o dispatcher a cada solicitação, como visto anteriormente.
// 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());Como resolver problemas frequentes?
Se o dispatcher parece ser ignorado no fetch nativo do Node.js, verifique se você importou o fetch do pacote undici. Versões diferentes podem causar incompatibilidade, então o método mais seguro é importar fetch e ProxyAgent do mesmo pacote.
Resposta 407 indica credenciais inválidas. Verifique se após 'Basic' no token está o valor codificado em base64 do nome de usuário e senha. ECONNREFUSED geralmente indica porta incorreta. Use a porta HTTP para agentes HTTP e a porta SOCKS5 para agentes SOCKS.
- fetch e ProxyAgent estão no mesmo pacote undici
- 407: Verifique o token e os IPs registrados
- ECONNREFUSED: Diferença entre porta HTTP e SOCKS5
- Limite de tempo para todas as solicitações