Tetapan Proxy Node.js, Menyambungkan HTTP dan SOCKS5 Proxy ke fetch dan https
Panduan ini menerangkan cara menyambung HTTP proxy Socks5Proxy ke ProxyAgent undici dan SOCKS5 proxy ke socks-proxy-agent dalam Node.js 18+, serta kod untuk menerima dan memutar senarai melalui API.
Apa yang diperlukan untuk menggunakan proxy dalam Node.js?
Fetch yang terdapat dalam Node.js berfungsi dengan pustaka bernama undici dan secara lalai tidak membaca tetapan proxy. Jadi, HTTP proxy digunakan dengan menghantar ProxyAgent dari undici sebagai dispatcher, dan SOCKS5 proxy digunakan dengan menghantar socks-proxy-agent sebagai agen ke modul https Node.
Contoh menggunakan IP 198.51.100.23, port HTTP 8000, port SOCKS5 1080, username spx_user, dan password spx_pass. Semua kod dalam format modul ES (.mjs).
npm install undici socks-proxy-agentBagaimana untuk menyambung proksi HTTP ke fetch?
Masukkan alamat proxy ke dalam ProxyAgent, dan nama pengguna dan kata laluan ke dalam pilihan token sebagai nilai pengesahan Basic. Hantar ke fetch dari undici sebagai dispatcher, dan permintaan tersebut akan melalui proxy. Alamat HTTPS dihantar dalam mod CONNECT yang disulitkan.
Menggunakan semula ProxyAgent yang sama untuk pelbagai permintaan mempercepatkan sambungan. Buat satu agen per proxy dan gunakan bergilir-gilir.
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 IPBagaimana untuk menyambung ke proksi SOCKS5?
socks-proxy-agent adalah ejen yang digunakan dengan modul http dan https Node. Dengan menggunakan alamat socks5h, resolusi nama domain dilakukan oleh proksi. Contoh di bawah menghantar ejen ke https.get dan mengumpul serta mencetak badan respons.
Untuk pustaka yang beroperasi pada modul http seperti axios, menghantar ejen yang sama ke httpAgent dan httpsAgent akan menghantar permintaan melalui SOCKS5.
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));Bagaimana cara menerima senarai melalui API dan mengitar semula?
Mulakan dengan menerima senarai melalui API dan buat agen untuk setiap proksi, kemudian gunakan agen seterusnya untuk setiap permintaan. Kod di bawah menerima senarai HTTP dalam format ip:port:user:pass, membuat array ProxyAgent, dan mencuba semula dengan proksi seterusnya jika gagal.
Sila tambahkan had masa dengan AbortSignal.timeout pada setiap permintaan. Permintaan tanpa respons akan memperlahankan keseluruhan kerja.
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);Bagaimana kod berubah dengan pengesahan IP?
Daftarkan IPv4 pelayan yang menjalankan Node.js di papan pemuka, kemudian anda boleh menggunakan ProxyAgent dengan hanya alamat tanpa pilihan token. SOCKS5 juga boleh digunakan tanpa nama pengguna dan kata laluan seperti socks5h://198.51.100.23:1080. Ini memudahkan penyebaran ke pelbagai pelayan tanpa menyimpan kata laluan dalam pembolehubah persekitaran atau kod.
Bagaimana untuk menyambung jika menggunakan axios?
axios beroperasi pada modul http dan https Node, jadi anda boleh menggunakan proksi dengan menghantar ejen. Untuk SOCKS5, gunakan socks-proxy-agent untuk httpAgent dan httpsAgent, dan tetapkan pilihan proxy axios kepada false untuk mengelakkan pertindihan.
HTTP proxy juga dapat dihubungkan dengan memasukkan host, port, auth ke opsi proxy axios, tetapi untuk alamat HTTPS, menggunakan agen lebih stabil. Paket https-proxy-agent memungkinkan Anda menghubungkan HTTP proxy dengan struktur yang sama.
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);Apakah perkara yang perlu diperhatikan semasa menghantar banyak permintaan serentak?
Jika anda memulakan ribuan permintaan sekaligus dengan Promise.all, terlalu banyak sambungan akan dibuka, membebankan proxy dan laman web sasaran. Tetapkan bilangan permintaan yang diproses serentak dan gunakan barisan tugas untuk memprosesnya. Anda boleh membuat fungsi kecil sendiri atau menggunakan pakej seperti p-limit.
Membahagikan bilangan sambungan serentak secara sama rata antara proksi menghalang permintaan daripada tertumpu pada satu IP. Pelan kongsi termasuk 500 sambungan serentak, jadi sila sesuaikan jumlah permintaan serentak dalam had tersebut.
Bolehkah saya menggunakan pembolehubah persekitaran untuk menerapkan proksi pada semua permintaan?
EnvHttpProxyAgent dari undici membaca pembolehubah persekitaran HTTP_PROXY, HTTPS_PROXY, dan NO_PROXY untuk menentukan proksi. Dengan mendaftarkannya melalui setGlobalDispatcher, semua fetch dalam proses tersebut akan melalui proksi. Ini memudahkan apabila banyak pustaka menggunakan fetch secara dalaman.
Tetapan global menggunakan IP yang sama untuk semua permintaan, lebih sesuai untuk alat atau ujian yang memerlukan akses dari satu negara berbanding tugas pengumpulan data yang memerlukan pengagihan IP. Jika anda memerlukan putaran, lulus dispatcher untuk setiap permintaan seperti yang dilihat sebelumnya.
// 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());Bagaimana cara menyelesaikan masalah yang sering terjadi?
Jika dispatcher yang anda hantar ke fetch bawaan Node.js kelihatan diabaikan, pastikan anda telah mengambil fetch dari pakej undici. Jika versi fetch bawaan dan undici yang dipasang berbeza, agen mungkin tidak sepadan, jadi cara yang paling pasti adalah dengan mengambil fetch dan ProxyAgent dari pakej yang sama.
Respons 407 menunjukkan maklumat pengesahan salah. Pastikan nilai token Basic diikuti dengan nama pengguna:kata laluan yang ditukar ke base64. ECONNREFUSED sering berlaku apabila port salah. Gunakan port HTTP untuk agen HTTP dan port SOCKS5 untuk agen SOCKS.
- fetch dan ProxyAgent adalah dari pakej undici yang sama
- 407: Semula nilai token dan IP yang didaftarkan
- ECONNREFUSED: Membedakan Port HTTP dan SOCKS5
- Had masa untuk semua permintaan