Node.js の HTTP クライアントはそれぞれプロキシの扱いが異なり、その半数はヘルパーパッケージなしではプロキシの認証をまったく処理できません。axios は一部のバージョンで HTTPS ターゲットに対して自身の proxy オプションを黙って無視しますし、ネイティブの fetch にはプロキシオプションが一切ありません。そしてエラーメッセージ — ECONNRESET、407、あるいは単にハングするだけ — は何も教えてくれません。
これは axios、got、node-fetch、ネイティブ fetch(undici)、superagent を認証付き residential プロキシ経由でルーティングするための、完全かつ動作する決定版リファレンスです。私たちの Python ガイド(requests/httpx/aiohttp、Scrapy)の Node 版です。すべての例は標準のプレースホルダー形式を使っています — 実際の認証情報に差し替えてください:
socks5h://USERNAME:[email protected]:913
組み込みの proxy オプションを使わないこと。proxy agent を使うこと。 Node の HTTP クライアントは接続処理を「agent」オブジェクトに委譲します。agent パッケージ(https-proxy-agent、socks-proxy-agent)は CONNECT トンネリングと認証を正しく実装しています。組み込みオプションはしばしばそれができません — axios の proxy 設定がもっとも悪名高い例です。
npm install socks-proxy-agent https-proxy-agent
const axios = require("axios");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const res = await axios.get("https://api.ipify.org?format=json", {
httpAgent: agent, // for http:// targets
httpsAgent: agent, // for https:// targets
proxy: false, // IMPORTANT: disable axios's own proxy handling
});
console.log(res.data); // -> the proxy's exit IP
見落とされがちな 2 点: httpAgent と httpsAgent の両方を設定する必要があること(axios はターゲットのスキームで選択します)。そして proxy: false を設定して、axios が自分の agent の上にさらに HTTP_PROXY 環境変数を適用しようとしないようにする必要があることです。
const got = require("got");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const body = await got("https://api.ipify.org?format=json", {
agent: { http: agent, https: agent },
}).json();
got で保護されたターゲットをスクレイピングするなら、代わりに got-scraping を見てください — 同じ API に加えて、ブラウザライクなヘッダー生成と HTTP/2 フィンガープリントの模倣が付いています(なぜそれが重要なのか: JA3/JA4 の解説)。
Node 組み込みの fetch は undici 由来で、プロキシ環境変数を無視し、agent オプションもありません。undici 流のやり方は dispatcher です:
const { ProxyAgent } = require("undici");
// undici's ProxyAgent speaks HTTP CONNECT (use your HTTP proxy port)
const dispatcher = new ProxyAgent({
uri: "http://us.jibaoproxy.com:1000",
token: "Basic " + Buffer.from("USERNAME:PASSWORD").toString("base64"),
});
const res = await fetch("https://api.ipify.org?format=json", { dispatcher });
console.log(await res.json());
注意: undici の ProxyAgent は HTTP プロキシ専用です。ネイティブ fetch で SOCKS5 を使うには、ローカルのフォワーダーを前段に置くか、socks agent を受け付けるクライアント(上記の axios/got)を使ってください。
const fetch = require("node-fetch");
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent(
"socks5h://USERNAME:[email protected]:913"
);
const res = await fetch("https://api.ipify.org?format=json", { agent });
ローテーティングな residential ゲートウェイを使えば、IP リストを管理する必要はありません — ゲートウェイは接続ごとに新しい exit を渡すか、session id ごとに 1 つの exit を保持します。Node では、これがアイデンティティごとに 1 つの agent へきれいにマッピングされます:
// Sticky: same session id -> same exit IP across requests
function identityAgent(sessionId) {
return new SocksProxyAgent(
`socks5h://USERNAME-session-${sessionId}:[email protected]:913`
);
}
// Account A keeps IP A, account B keeps IP B - cookies and IP move together
const agentA = identityAgent("acct_a");
const agentB = identityAgent("acct_b");
同一アイデンティティ内では接続プーリングのために agent を再利用してください。決して 1 つの agent を複数のアイデンティティで共有しないこと。いつローテーションし、いつ sticky にするかはそれ自体が 1 つのトピックです — sticky vs rotating セッションを参照してください。
| 症状 | 原因 | 対処 |
|---|---|---|
407 Proxy Authentication Required | 認証情報がプロキシに届いていない | user:pass をクライアント設定ではなく agent の URL に入れる |
| axios が http:// では動くが https:// で失敗する | httpAgent しか設定していない | httpsAgent も設定し、proxy: false にする |
すぐに ECONNRESET になる | ポートが違う / プロトコルが違う(HTTP ポートに SOCKS agent) | agent の種類をポートに合わせる |
| DNS リークする / 内部ホスト名が解決できない | socks5:// は DNS をローカルで解決する | socks5h:// を使う — h がホスト名をプロキシ経由で送る |
| ネイティブ fetch が HTTP_PROXY を無視する | undici は環境変数を読まない | dispatcher を明示的に渡す |
| ローカルでは動くが対象サイトで 403 になる | プロキシのバグではない — TLS フィンガープリント | got-scraping か本物のブラウザを使う。TLS ガイドを参照 |
socks-proxy-agent / https-proxy-agent)を使うこと。組み込みのプロキシオプションは決して信用しない。proxy: false。got: agent: {http, https}。ネイティブ fetch: undici の ProxyAgent dispatcher。socks5h:// を使い、DNS をプロキシ経由で解決すること — リークなし。SOCKS5 + HTTP エンドポイント、sticky またはローテーティング、GB 単位の課金 — 500MB の無料トラフィック、カード不要。
無料トライアルを始める新規ユーザーは登録時に500MBを獲得、さらに初回チャージにボーナスが付きます。期間限定オファーです。