# พร็อกซีเรซิเดนเชียลหมุนเวียนใน Node.js: undici, axios, got และ SOCKS5

> พร็อกซีเรซิเดนเชียลหมุนเวียนใน Node.js: undici ProxyAgent ใช้กับ fetch, axios และ got กับ proxy agents, SOCKS5, จำกัดต่อโฮสต์ โค้ดที่ตรวจไวยากรณ์แล้ว

- URL: https://crawlrelay.com/th/docs/node/
- อัปเดตล่าสุด: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

fetch ใน Node.js ที่ติดตั้งมาไม่สนใจการตั้งค่าพร็อกซีถ้าไม่กำหนด dispatcher นี่คือรูปแบบที่ใช้งานได้ ไลบรารีตามไลบรารี พร้อมกับตัวจำกัดต่อโฮสต์โดยไม่ต้องพึ่งพาอื่น

**คำตอบด่วน — ฉันใช้พร็อกซีหมุนเวียนใน Node.js อย่างไร?**

กับ fetch สร้าง undici `ProxyAgent` สำหรับ `http://gw.crawlrelay.com:7777` แล้วส่งเป็น `dispatcher` กับ axios หรือ got ส่ง proxy agent เช่น `https-proxy-agent` หรือ `hpagent` และตั้งค่า `proxy: false` ใน axios **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 | `agent: { https: new HttpsProxyAgent({ proxy }) }` จาก hpagent |
| SOCKS5 | `socks-proxy-agent` กับ URL แบบ `socks5h://` บนพอร์ต 7778 |
| IP ใหม่ทุกคำขอ | เอเจนต์ใหม่หรือ session ID ใหม่ทุกคำขอ; การเชื่อมต่อแบบ pooled จะรักษา exit เดิมไว้ |
| รูปแบบโมดูล | ตัวอย่างคือ ES modules (`.mjs` หรือ `"type": "module"`) ที่ใช้ top-level await |

## ฉันจะใช้พร็อกซีกับ fetch ของ Node อย่างไร?

fetch แบบ global ใน Node `fetch` สร้างบน undici แต่เริ่มต้นไม่รองรับ `HTTP_PROXY` หรือ `HTTPS_PROXY` ติดตั้ง undici แล้วส่ง `ProxyAgent` เป็น dispatcher ฟิลด์ `token` จะส่งข้อมูลรับรองเป็น header `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 อย่างไร?

อย่าใช้ตัวเลือก `proxy` ของ axios กับเว็บ HTTPS: มันส่งคำขอไปยังพร็อกซีโดยไม่มีการเปิด tunnel CONNECT ซึ่งพร็อกซีหลายแห่งจะปฏิเสธ ปิดใช้งานด้วย `proxy: false` แล้วส่ง agent ที่เปิด tunnel แบบถูกต้อง

*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 ใช้ agent หนึ่งตัวต่อโปรโตคอล hpagent ปฏิบัติตาม `http.Agent` ของ Node: ปิด keep-alive เว้นแต่คุณจะส่ง `keepAlive: true` ปล่อยให้ปิด หรือกำหนด `keepAlive: false` ตามด้านล่าง เมื่อคุณต้องการให้แต่ละคำขอใช้การเชื่อมต่อใหม่ และโดยปกติจะเป็น exit ใหม่

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

## ฉันจะใช้ SOCKS5 ใน Node.js อย่างไร?

ใช้ `socks-proxy-agent` กับ scheme `socks5h://` เพื่อให้ hostname ถูกแปลงที่ exit ทำงานกับโมดูล `http` และ `https` ของ Node และกับไลบรารีใดๆ ที่รับ agent

*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` กับ URLs กว่า 10,000 รายการ จะเปิด 10,000 คำขอพร้อมกัน ตัวจำกัดขนาดเล็กต่อ hostname จะช่วยให้แต่ละไซต์อยู่ในระดับที่สุภาพขณะที่การรวบรวมทำงานแบบขนาน โค้ดด้านล่างไม่พึ่งพาอะไรและทำงานกับไคลเอนต์ใดๆ ที่กล่าวมา

*ตัวจำกัดต่อโฮสต์ + 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?

Agents รวบรวมการเชื่อมต่อ และการเชื่อมต่อ pooled จะรักษา exit ที่เปิดไว้ สำหรับ IP ใหม่ในแต่ละคำขอ สร้าง agent ใหม่ต่อคำขอแล้วปิดหลังใช้ ปิด keep-alive ใน agent หรือใส่ `-session-<id>` เฉพาะใน username ของแต่ละคำขอ

`ECONNRESET` และ `socket hang up` มักเกิดจากการใช้ซ็อกเก็ต pooled ที่อีกฝ่ายปิดไปแล้ว หรือ exit ที่หลุด ลองส่งคำขอ GET ใหม่อีกครั้งด้วยการเชื่อมต่อใหม่ [หน้าการรีเซ็ตการเชื่อมต่อ](https://crawlrelay.com/th/docs/errors/connection-reset/) อธิบายรายละเอียด]

## คำถามเกี่ยวกับ Node.js และพร็อกซี

### Node.js fetch รองรับ HTTP_PROXY หรือไม่?

ไม่ใช่โดยค่าเริ่มต้นในเวอร์ชันที่โปรเจกต์ส่วนใหญ่นิยมใช้ตอนนี้: fetch แบบ global จะไม่สนใจตัวแปรสภาพแวดล้อมพร็อกซีถ้าไม่ส่ง dispatcher ใช้ undici `ProxyAgent` ตามตัวอย่างด้านบน หรือกำหนด global dispatcher ด้วย undici `setGlobalDispatcher()` ถ้าต้องการให้ทุกคำขอในโปรเซสใช้พร็อกซี

### ทำไม axios ถึงล้มเหลวกับเว็บ HTTPS ที่อยู่หลังพร็อกซี?

ตัวเลือก `proxy` ในตัวของ axios ส่งคำขอ HTTPS ไปยังพร็อกซีในรูปแบบที่พร็อกซีหลายแห่งไม่ยอมรับ แทนที่จะเปิด tunnel CONNECT ให้ตั้ง `proxy: false` และส่ง `HttpsProxyAgent` เป็น `httpsAgent` จากนั้นคำขอจะวิ่งผ่าน tunnel ที่ถูกต้อง และ TLS จะอยู่ระหว่างโค้ดของคุณกับเว็บไซต์

### ฉันจะส่งคำขอจากหลายประเทศใน Node.js process เดียวได้อย่างไร?

สร้าง agent หนึ่งตัวต่อประเทศ แต่ละตัวมี username ของตัวเอง เช่น `USERNAME-country-de` หรือ `USERNAME-country-jp` แล้วเลือก agent ตามคำขอ Agents ใช้งานง่ายและถูก และแยกกันเก็บ pool การเชื่อมต่อและ exit ของแต่ละ agent

### ฉันควรกำหนด timeout ไหนใน Node.js?

ควรกำหนดทุกครั้ง: `AbortSignal.timeout(30000)` สำหรับ fetch, `timeout: 30000` สำหรับ axios, `timeout: { request: 30000 }` สำหรับ got สามสิบวินาทีเหมาะกับหน้า HTML เป้าหมายช้าและ exit มือถือให้เวลาถึง 60 วินาที และลองใหม่ด้วยการเชื่อมต่อใหม่แทนการรอนานกว่า

**เชื่อมต่อเครื่องรวบรวมข้อมูล Node.js ของคุณ** US$5.94 สำหรับ 10 GB, US$0.50/GB จาก 50 GB. [ดูราคา](https://crawlrelay.com/th/pricing/) · [คู่มือ Puppeteer](https://crawlrelay.com/th/docs/puppeteer/)

---

CrawlRelay: CrawlRelay คือพร็อกซีเรซิเดนเชียลหมุนเวียนพร้อมพร็อกซีมือถือ 4G/5G สำหรับนักพัฒนา เหมาะกับสแครปเปอร์และระบบจัดการข้อมูล AI: เติมเงินจ่ายตามการใช้งานจาก US$0.50/GB จ่ายด้วยคริปโต ไม่ต้องอัปโหลดบัตรประชาชน ไม่ต้อง KYC — ไม่ต้องใช้บัตรประชาชน ไม่ต้องถ่ายเซลฟี่ ไม่ต้องใช้เอกสาร จ่ายด้วยคริปโต
