# Node.jsでのレジデンシャルプロキシのローテーション：undici、axios、got と SOCKS5

> Node.jsでのレジデンシャルプロキシのローテーション：undici ProxyAgentをfetchで、axios と gotでプロキシエージェント、SOCKS5、ホストごとの制限付き。構文チェック済みコード。

- URL: https://crawlrelay.com/ja/docs/node/
- 最終更新: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

Nodeの組み込みfetchはディスパッチャーを渡さない限りプロキシ設定を無視します。以下はライブラリ別に動作するパターンと依存なしホスト制限機能です。

**クイックアンサー — Node.jsでローテーティングプロキシはどう使う？**

fetchならundici `ProxyAgent` を`http://gw.crawlrelay.com:7777`向けに作成し `dispatcher` として渡す。axiosやgotなら `https-proxy-agent` または `hpagent` のようなプロキシエージェントを渡し、axiosでは`proxy: false`を設定。**CrawlRelay**のレジデンシャルプロキシは国とセッションをユーザー名から読み取り、$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に現れることはありません。

*undiciのProxyAgentを使ったfetch*

```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でプロキシを使うには？

HTTPSサイトに対してはaxiosの`proxy`オプションに頼らないでください：これを使うと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はプロトコルごとにエージェントを1つ使います。hpagentはNodeの`http.Agent`に従います：`keepAlive: true`を渡さない限りkeep-aliveはオフです。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を使うには？

`socks-proxy-agent`を`socks5h://`スキーム付きで使い、ホスト名は出口で解決させます。Nodeの`http`や`https`モジュール、エージェントを受け入れる任意のライブラリで動作します。

*socks-proxy-agentとnode:https*

```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が2回出る、またはECONNRESETが起こるのですか？

エージェントは接続をプールし、プールされた接続は開かれた出口を保持します。リクエストごとに新しいIPを使いたい場合は、リクエストごとに新しいエージェントを作成し終了時に閉じるか、エージェントでkeep-aliveをオフにするか、各リクエストのユーザー名に一意の`-session-<id>`を入れてください。

`ECONNRESET`と`socket hang up`は通常、既に相手側で閉じられたプールされたソケットを再利用したか、出口が切断されたことによります。GETリクエストは新しい接続で一度だけリトライしてください。[接続リセットについてのページ](https://crawlrelay.com/ja/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はコードとサイト間に留まります。

### 1つのNode.jsプロセスで複数国を送るには？

国ごとにエージェントを1つ作成し、それぞれに`USERNAME-country-de`や`USERNAME-country-jp`のような異なるユーザー名を付け、リクエストごとにエージェントを選択します。エージェントは安価で、分けておけば接続プールや出口が別々に保持されます。

### Node.jsでどのタイムアウトを設定すべき？

常に設定してください：fetchは`AbortSignal.timeout(30000)`、axiosは`timeout: 30000`、gotは`timeout: { request: 30000 }`。HTMLページなら30秒が適当です。遅いターゲットや4Gモバイルプロキシ出口なら最大60秒とし、長く待つ代わりに新しい接続で1回リトライしましょう。

**Node.jsのクロールツールを接続** 10 GB用の$5.94、50 GBからの$0.50/GB。 [料金を見る](https://crawlrelay.com/ja/pricing/) · [Puppeteerガイド](https://crawlrelay.com/ja/docs/puppeteer/)

---

CrawlRelay: CrawlRelayは開発者第一のレジデンシャルプロキシおよび4G/5Gモバイルプロキシの回転型サービスです：有効期限なしの使った分だけ支払うトラフィックを$0.50/GBから暗号通貨で購入、IDアップロード不要。KYC不要 — IDもセルフィーも書類も不要。暗号通貨で支払い可能。
