# Node.js에서 회전하는 레지덴셜 프록시: undici, axios, got, SOCKS5

> Node.js에서 회전하는 레지덴셜 프록시: undici ProxyAgent를 fetch, axios, got용으로 사용, SOCKS5, 호스트별 제한. 문법 검사된 코드 포함.

- URL: https://crawlrelay.com/ko/docs/node/
- 마지막 업데이트: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

Node 내장 fetch는 dispatcher를 제공하지 않으면 프록시 설정을 무시합니다. 라이브러리별로 작동하는 패턴과 종속성 없는 호스트별 제한기를 소개합니다.

**빠른 답변 — Node.js에서 회전 프록시를 어떻게 사용하나요?**

fetch를 사용할 땐 `http://gw.crawlrelay.com:7777`용 undici `ProxyAgent`를 생성해 `dispatcher`로 넘기세요. axios 또는 got는 `https-proxy-agent` 또는 `hpagent` 같은 프록시 에이전트를 넘기고 axios엔 `proxy: false`를 설정하세요. **CrawlRelay** 레지덴셜 프록시는 사용자명에서 국가와 세션을 읽습니다, 그리고 US$0.50/GB에서 제공합니다. KYC 없이 암호화폐로 결제 가능합니다.

## Node.js 설정 개요

| 속성 | 값 |
| --- | --- |
| fetch / undici | `new ProxyAgent({ uri, token })`, 그다음 `fetch(url, { dispatcher })` |
| axios | `httpsAgent: new HttpsProxyAgent(url)` 및 `proxy: false` |
| got | hpagent에서 `agent: { https: new HttpsProxyAgent({ proxy }) }` 받음 |
| SOCKS5 | 포트 7778에서 `socks5h://` URL로 `socks-proxy-agent` |
| 요청마다 새로운 IP | 요청마다 새로운 에이전트나 새로운 세션 ID; 풀링된 연결은 기존 출구 유지 |
| 모듈 형식 | 예시는 최상위 await가 포함된 ES 모듈(`.mjs` 또는 `"type": "module"`) 형식 |

## Node의 fetch에서 프록시를 어떻게 사용하나요?

Node의 전역 `fetch`는 undici 기반이며 기본적으로 `HTTP_PROXY` 또는 `HTTPS_PROXY`를 읽지 않습니다. undici를 설치하고 `ProxyAgent`를 디스패처로 전달하세요. `token` 필드는 자격 증명을 `Proxy-Authorization` 헤더로 보내서, 비밀번호가 기록될 수 있는 URL에 절대 나타나지 않게 합니다.

*fetch와 함께 사용하는 undici ProxyAgent*

```javascript
import { ProxyAgent, fetch } from "undici";

const credentials = Buffer.from("USERNAME-country-us:PASSWORD").toString("base64");
const dispatcher = new ProxyAgent({
  uri: "http://gw.crawlrelay.com:7777",
  token: `Basic ${credentials}`,
});

const res = await fetch("https://api.ipify.org?format=json", {
  dispatcher,
  signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
await dispatcher.close();
```

## axios에서 프록시는 어떻게 사용하나요?

axios 자체의 `proxy` 옵션은 HTTPS 사이트에서는 신뢰하지 마십시오: 이 옵션은 CONNECT 터널 없이 프록시로 요청을 보내 많은 프록시가 거부합니다. `proxy: false`로 비활성화하고 올바른 터널을 여는 에이전트를 전달하세요.

*axios + https-proxy-agent*

```javascript
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USERNAME-country-de:PASSWORD@gw.crawlrelay.com:7777");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });

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

## got에서 프록시는 어떻게 사용하나요?

got는 프로토콜 별로 하나의 에이전트를 사용합니다. hpagent는 Node의 `http.Agent`를 따릅니다: `keepAlive: true`를 전달하지 않으면 keep-alive가 꺼집니다. 요청마다 새로운 연결, 즉 보통 새로운 출구를 원할 때는 꺼두거나 아래처럼 `keepAlive: false`로 설정하세요.

*got + hpagent*

```javascript
import got from "got";
import { HttpsProxyAgent } from "hpagent";

const proxy = "http://USERNAME-country-fr:PASSWORD@gw.crawlrelay.com:7777";
const body = await got("https://api.ipify.org", {
  agent: { https: new HttpsProxyAgent({ proxy, keepAlive: false }) },
  timeout: { request: 30000 },
  retry: { limit: 2, statusCodes: [429, 502, 503, 504] },
}).text();
console.log(body);
```

## Node.js에서 SOCKS5는 어떻게 사용하나요?

호스트네임이 출구에서 해석되도록 `socks5h://` 스킴과 함께 `socks-proxy-agent`를 사용하세요. Node의 `http`와 `https` 모듈뿐 아니라 agent를 받는 모든 라이브러리에서 작동합니다.

*node:https와 함께 쓰는 socks-proxy-agent*

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

const agent = new SocksProxyAgent("socks5h://USERNAME-country-gb:PASSWORD@gw.crawlrelay.com:7778");

const req = https.get("https://api.ipify.org", { agent, timeout: 30000 }, (res) => {
  let body = "";
  res.on("data", (chunk) => (body += chunk));
  res.on("end", () => console.log(res.statusCode, body));
});
req.on("timeout", () => req.destroy(new Error("timeout after 30 s")));
req.on("error", (err) => console.error(err.code, err.message));
```

## 라이브러리 없이 호스트별 동시성은 어떻게 제한하나요?

`Promise.all`에서 10,000개 URL을 한꺼번에 열면 10,000개의 요청이 동시에 발생합니다. 호스트별로 작은 제한자는 사이트마다 적당한 레벨을 유지하며 전체 크롤은 병렬로 실행합니다. 아래 버전은 의존성이 없고 위 클라이언트 어디에서나 작동합니다.

*호스트별 제한자 + undici*

```javascript
import { ProxyAgent, fetch } from "undici";

const PER_HOST = 4;
const active = new Map();
const waiting = new Map();
const dispatcher = new ProxyAgent("http://USERNAME-country-us:PASSWORD@gw.crawlrelay.com:7777");

async function withHostSlot(url, task) {
  const host = new URL(url).hostname;
  while ((active.get(host) ?? 0) >= PER_HOST) {
    await new Promise((resolve) => {
      if (!waiting.has(host)) waiting.set(host, []);
      waiting.get(host).push(resolve);
    });
  }
  active.set(host, (active.get(host) ?? 0) + 1);
  try {
    return await task();
  } finally {
    active.set(host, active.get(host) - 1);
    waiting.get(host)?.shift()?.();
  }
}

const urls = ["https://example.com/", "https://example.org/", "https://example.net/"];
const results = await Promise.all(
  urls.map((url) =>
    withHostSlot(url, async () => {
      const res = await fetch(url, { dispatcher, signal: AbortSignal.timeout(30000) });
      return [url, res.status, (await res.arrayBuffer()).byteLength];
    }).catch((err) => [url, err.name, 0])
  )
);
console.table(results);
await dispatcher.close();
```

## 왜 같은 IP가 두 번 나오거나 ECONNRESET 오류가 발생하나요?

에이전트는 연결을 풀링하며, 풀링된 연결은 열릴 때 정해진 출구를 유지합니다. 요청마다 새 IP가 필요하면 요청당 새로운 에이전트를 생성하고 닫거나, 에이전트에서 keep-alive를 끄거나, 각 요청의 사용자 이름에 고유한 `-session-<id>`를 넣으세요.

`ECONNRESET`와 `socket hang up` 오류는 보통 상대가 이미 닫은 풀링된 소켓을 재사용하거나 출구가 끊긴 경우 발생합니다. GET 요청은 새 연결에서 한 번 재시도하세요. 자세한 내용은 [연결 재설정 페이지](https://crawlrelay.com/ko/docs/errors/connection-reset/)] 참고.

## Node.js와 프록시: 질문 모음

### Node.js fetch는 HTTP_PROXY를 지원하나요?

대부분의 현재 프로젝트에서 사용하는 버전은 기본 지원하지 않습니다: 전역 fetch는 디스패처를 전달하지 않으면 프록시 환경 변수를 무시합니다. 위와 같이 undici `ProxyAgent`를 사용하거나, 프로세스 내 모든 요청에 프록시를 사용하려면 undici의 `setGlobalDispatcher()`로 전역 디스패처를 설정하세요.

### 프록시 뒤 HTTPS 사이트에서 axios가 실패하는 이유는?

axios 내장 `proxy` 옵션은 많은 프록시가 거부하는 형태로 HTTPS 요청을 프록시로 보내며 CONNECT 터널을 열지 않습니다. `proxy: false`을 설정하고 `httpsAgent`로 `HttpsProxyAgent`를 전달하세요. 요청은 올바른 터널을 통해 이동하며 TLS는 코드와 사이트 간에 유지됩니다.

### 한 Node.js 프로세스에서 여러 국가를 어떻게 할당하나요?

국가별로 에이전트를 만들어 각각 `USERNAME-country-de` 또는 `USERNAME-country-jp` 같은 고유 사용자 이름을 부여하고 요청마다 에이전트를 선택하세요. 에이전트는 저렴하며 구분해서 유지하면 연결 풀과 출구도 각기 별도로 유지됩니다.

### Node.js에서 어느 타임아웃을 설정해야 하나요?

반드시 설정하세요: fetch는 `AbortSignal.timeout(30000)`, axios는 `timeout: 30000`, got는 `timeout: { request: 30000 }`. HTML 페이지에는 30초가 적당하며 느린 대상과 모바일 출구에는 최대 60초를 주고, 긴 대기 대신 새 연결에서 한 번 재시도 하세요.

**Node.js 크롤러 연결하기** 10 GB용 US$5.94, 50 GB에서 가져온 US$0.50/GB. [가격 확인](https://crawlrelay.com/ko/pricing/) · [Puppeteer 가이드](https://crawlrelay.com/ko/docs/puppeteer/)

---

CrawlRelay: CrawlRelay는 개발자 중심의 회전형 레지덴셜 프록시 및 4G/5G 모바일 프록시 서비스로, 스크래퍼와 AI 데이터 파이프라인을 위한 비만료 선불 과금 트래픽을 US$0.50/GB부터 암호화폐로 결제하며 신분증 업로드가 없습니다. KYC 없이 — 신분증, 셀카, 문서 없이 이용 가능. 암호화폐로 결제하세요.
