Saat mengembangkan aplikasi Node.js untuk pengambilan data, otomatisasi, atau bekerja dengan API, sering kali diperlukan penggunaan server proxy. Ini memungkinkan untuk menghindari batasan geografis, mendistribusikan beban, dan menghindari pemblokiran berdasarkan IP. Dalam panduan ini, kita akan membahas semua cara untuk mengatur proxy di Node.js — dari teknik dasar hingga teknik lanjutan dengan rotasi dan penanganan kesalahan.
Konsep dasar bekerja dengan proxy di Node.js
Server proxy di Node.js berfungsi sebagai perantara antara aplikasi Anda dan server tujuan. Ketika Anda mengirim permintaan HTTP melalui proxy, aplikasi Anda terlebih dahulu terhubung ke server proxy, yang kemudian meneruskan permintaan ke alamat akhir. Ini memungkinkan untuk menyembunyikan alamat IP asli server Anda dan menggunakan alamat IP proxy.
Di Node.js, ada beberapa cara dasar untuk bekerja dengan proxy tergantung pada pustaka yang digunakan untuk permintaan HTTP. Opsi yang paling populer adalah:
- Modul bawaan http/https — fungsionalitas dasar tanpa ketergantungan tambahan
- Axios — pustaka populer dengan API yang nyaman dan dukungan untuk promise
- Got — alternatif modern dengan dukungan TypeScript
- node-fetch — implementasi Fetch API untuk Node.js
- request — pustaka yang sudah usang, tetapi masih digunakan (tidak disarankan untuk proyek baru)
Server proxy mendukung berbagai protokol. Untuk bekerja dengan Node.js, protokol yang paling sering digunakan adalah:
| Protokol | Deskripsi | Penggunaan |
|---|---|---|
| HTTP | Protokol dasar untuk koneksi yang tidak terenkripsi | Pengambilan data, bekerja dengan API tanpa SSL |
| HTTPS | Proxy dengan dukungan enkripsi SSL/TLS | Koneksi aman, bekerja dengan API yang dilindungi |
| SOCKS5 | Protokol universal untuk semua jenis lalu lintas | WebSocket, UDP, skenario kompleks |
Untuk tugas pengambilan data dan otomatisasi, pengembang sering menggunakan proxy residensial, karena mereka memiliki alamat IP nyata dari pengguna rumah dan jarang terkena pemblokiran dari situs tujuan.
Pengaturan proxy melalui modul http/https bawaan
Node.js menyediakan modul bawaan http dan https untuk bekerja dengan permintaan HTTP. Untuk menghubungkan proxy, Anda dapat menggunakan pustaka http-proxy-agent atau https-proxy-agent.
Pertama, instal paket yang diperlukan:
npm install http-proxy-agent https-proxy-agent
Contoh penggunaan proxy HTTP dengan modul bawaan:
const http = require('http');
const { HttpProxyAgent } = require('http-proxy-agent');
// Pengaturan proxy
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpProxyAgent(proxyUrl);
// Opsi permintaan
const options = {
hostname: 'api.example.com',
path: '/endpoint',
method: 'GET',
agent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
};
// Melakukan permintaan
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response:', data);
});
});
req.on('error', (error) => {
console.error('Permintaan gagal:', error.message);
});
req.end();
Untuk koneksi HTTPS, gunakan https-proxy-agent:
const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
const options = {
hostname: 'api.example.com',
path: '/secure-endpoint',
method: 'GET',
agent: agent
};
https.get(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response aman:', data);
});
}).on('error', (error) => {
console.error('Permintaan HTTPS gagal:', error.message);
});
Pendekatan ini memberikan kontrol maksimum atas permintaan, tetapi memerlukan lebih banyak kode untuk menangani promise dan kesalahan. Untuk sebagian besar tugas, lebih nyaman menggunakan pustaka khusus.
Bekerja dengan proxy di pustaka Axios
Axios — salah satu pustaka paling populer untuk permintaan HTTP di Node.js. Ini menyediakan API yang nyaman untuk mengatur proxy dan secara otomatis menangani promise.
Instal Axios:
npm install axios
Pengaturan dasar proxy di Axios terlihat sebagai berikut:
const axios = require('axios');
// Cara 1: Mengatur proxy dalam konfigurasi permintaan
axios.get('https://api.example.com/data', {
proxy: {
protocol: 'http',
host: 'proxy-server.com',
port: 8080,
auth: {
username: 'your-username',
password: 'your-password'
}
}
})
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
console.error('Kesalahan:', error.message);
});
Untuk penggunaan berulang dari pengaturan proxy yang sama, nyaman untuk membuat instance Axios dengan konfigurasi yang sudah ditentukan:
const axios = require('axios');
// Membuat instance dengan pengaturan proxy
const axiosWithProxy = axios.create({
proxy: {
protocol: 'http',
host: 'proxy-server.com',
port: 8080,
auth: {
username: 'your-username',
password: 'your-password'
}
},
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
// Menggunakan instance
async function fetchData() {
try {
const response = await axiosWithProxy.get('https://api.example.com/data');
console.log('Response:', response.data);
return response.data;
} catch (error) {
console.error('Permintaan gagal:', error.message);
throw error;
}
}
fetchData();
Untuk bekerja dengan proxy HTTPS melalui metode CONNECT, Anda dapat menggunakan agen tambahan:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const httpsAgent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
httpsAgent: httpsAgent,
timeout: 15000
});
// Menggunakan
axiosInstance.get('https://api.example.com/secure-data')
.then(response => console.log(response.data))
.catch(error => console.error(error.message));
Axios secara otomatis menangani pengalihan dan mendukung interceptor untuk logging dan penanganan kesalahan, yang menjadikannya pilihan yang sangat baik untuk proyek yang banyak menggunakan proxy.
Pengaturan proxy di got dan node-fetch
Got — alternatif modern untuk Axios dengan dukungan TypeScript yang sangat baik dan kemampuan penanganan kesalahan yang canggih. Node-fetch mengimplementasikan standar Fetch API untuk Node.js.
Bekerja dengan proxy di Got
Instal Got dan agen yang diperlukan:
npm install got https-proxy-agent
Contoh pengaturan proxy di Got:
const got = require('got');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = {
https: new HttpsProxyAgent(proxyUrl)
};
// Membuat instance Got dengan proxy
const gotWithProxy = got.extend({
agent: agent,
timeout: {
request: 10000
},
retry: {
limit: 3,
methods: ['GET', 'POST']
}
});
// Menggunakan
async function fetchWithGot() {
try {
const response = await gotWithProxy('https://api.example.com/data');
console.log('Response:', JSON.parse(response.body));
} catch (error) {
console.error('Permintaan Got gagal:', error.message);
}
}
fetchWithGot();
Bekerja dengan proxy di node-fetch
Node-fetch memerlukan pengaturan agen yang jelas untuk bekerja dengan proxy:
npm install node-fetch https-proxy-agent
const fetch = require('node-fetch');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
async function fetchWithProxy() {
try {
const response = await fetch('https://api.example.com/data', {
agent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
});
if (!response.ok) {
throw new Error(`Kesalahan HTTP! status: ${response.status}`);
}
const data = await response.json();
console.log('Data:', data);
return data;
} catch (error) {
console.error('Fetch gagal:', error.message);
throw error;
}
}
fetchWithProxy();
Got menyediakan fungsionalitas yang lebih kaya dari kotak (pengulangan otomatis, timeout, penanganan kesalahan), sementara node-fetch lebih dekat ke Fetch API standar dan cocok untuk pengembang yang akrab dengan JavaScript di browser.
Menghubungkan proxy SOCKS5 melalui socks-proxy-agent
SOCKS5 — protokol proxy universal yang bekerja pada tingkat yang lebih rendah daripada HTTP/HTTPS. Ini mendukung semua jenis lalu lintas, termasuk koneksi UDP dan WebSocket. Untuk bekerja dengan SOCKS5 di Node.js, digunakan pustaka socks-proxy-agent.
Instal paket yang diperlukan:
npm install socks-proxy-agent
Contoh penggunaan proxy SOCKS5 dengan berbagai pustaka:
const { SocksProxyAgent } = require('socks-proxy-agent');
const https = require('https');
// Pengaturan proxy SOCKS5 dengan otorisasi
const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const agent = new SocksProxyAgent(proxyUrl);
const options = {
hostname: 'api.example.com',
path: '/endpoint',
method: 'GET',
agent: agent
};
https.get(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response SOCKS5:', data);
});
}).on('error', (error) => {
console.error('Permintaan SOCKS5 gagal:', error.message);
});
Menggunakan SOCKS5 dengan Axios:
const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');
const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const httpsAgent = new SocksProxyAgent(proxyUrl);
const httpAgent = new SocksProxyAgent(proxyUrl);
const axiosWithSocks = axios.create({
httpAgent: httpAgent,
httpsAgent: httpsAgent,
timeout: 15000
});
async function fetchViaSocks5() {
try {
const response = await axiosWithSocks.get('https://api.example.com/data');
console.log('Data melalui SOCKS5:', response.data);
return response.data;
} catch (error) {
console.error('Kesalahan permintaan SOCKS5:', error.message);
throw error;
}
}
fetchViaSocks5();
Proxy SOCKS5 sangat berguna untuk tugas yang memerlukan kerja dengan protokol non-standar atau ketika fleksibilitas maksimum diperlukan. Banyak penyedia menawarkan proxy seluler dengan dukungan SOCKS5, yang memungkinkan untuk meniru lalu lintas seluler untuk bekerja dengan API seluler.
Implementasi rotasi proxy untuk mendistribusikan beban
Saat mengambil data dalam jumlah besar atau bekerja dengan API yang memiliki batasan jumlah permintaan dari satu IP, perlu menggunakan rotasi proxy. Ini memungkinkan untuk mendistribusikan permintaan di antara beberapa server proxy dan menghindari pemblokiran.
Contoh implementasi rotasi proxy sederhana:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
class ProxyRotator {
constructor(proxyList) {
this.proxyList = proxyList;
this.currentIndex = 0;
}
// Mendapatkan proxy berikutnya secara melingkar
getNextProxy() {
const proxy = this.proxyList[this.currentIndex];
this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
return proxy;
}
// Mendapatkan proxy acak
getRandomProxy() {
const randomIndex = Math.floor(Math.random() * this.proxyList.length);
return this.proxyList[randomIndex];
}
// Membuat instance Axios dengan proxy saat ini
createAxiosInstance(useRandom = false) {
const proxyUrl = useRandom ? this.getRandomProxy() : this.getNextProxy();
const agent = new HttpsProxyAgent(proxyUrl);
return axios.create({
httpsAgent: agent,
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
}
}
// Daftar proxy
const proxyList = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080',
'http://user4:pass4@proxy4.example.com:8080'
];
const rotator = new ProxyRotator(proxyList);
// Menggunakan rotasi
async function fetchWithRotation(url) {
const axiosInstance = rotator.createAxiosInstance();
try {
const response = await axiosInstance.get(url);
console.log('Sukses dengan proxy');
return response.data;
} catch (error) {
console.error('Permintaan gagal:', error.message);
throw error;
}
}
// Contoh pengambilan data massal dengan rotasi
async function massiveParsing(urls) {
const results = [];
for (const url of urls) {
try {
const data = await fetchWithRotation(url);
results.push({ url, success: true, data });
// Penundaan antara permintaan
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
results.push({ url, success: false, error: error.message });
}
}
return results;
}
// Menjalankan pengambilan data
const urlsToParse = [
'https://api.example.com/data/1',
'https://api.example.com/data/2',
'https://api.example.com/data/3',
'https://api.example.com/data/4',
'https://api.example.com/data/5'
];
massiveParsing(urlsToParse)
.then(results => console.log('Hasil pengambilan data:', results))
.catch(error => console.error('Kesalahan pengambilan data:', error));
Contoh yang lebih canggih dengan pelacakan status proxy dan pengecualian otomatis untuk yang tidak berfungsi:
class AdvancedProxyRotator {
constructor(proxyList, maxFailures = 3) {
this.proxyList = proxyList.map(url => ({
url,
failures: 0,
active: true,
lastUsed: null
}));
this.maxFailures = maxFailures;
this.currentIndex = 0;
}
// Mendapatkan proxy aktif
getActiveProxy() {
const activeProxies = this.proxyList.filter(p => p.active);
if (activeProxies.length === 0) {
throw new Error('Tidak ada proxy aktif yang tersedia');
}
// Mencari proxy yang belum digunakan paling lama
const proxy = activeProxies.reduce((oldest, current) => {
if (!oldest.lastUsed) return oldest;
if (!current.lastUsed) return current;
return current.lastUsed < oldest.lastUsed ? current : oldest;
});
proxy.lastUsed = Date.now();
return proxy;
}
// Menandai proxy sebagai sukses
markSuccess(proxyUrl) {
const proxy = this.proxyList.find(p => p.url === proxyUrl);
if (proxy) {
proxy.failures = 0;
}
}
// Menandai proxy sebagai gagal
markFailure(proxyUrl) {
const proxy = this.proxyList.find(p => p.url === proxyUrl);
if (proxy) {
proxy.failures++;
if (proxy.failures >= this.maxFailures) {
proxy.active = false;
console.warn(`Proxy ${proxyUrl} dinonaktifkan setelah ${proxy.failures} kegagalan`);
}
}
}
// Membuat instance Axios dengan rotasi
async createAxiosInstance() {
const proxy = this.getActiveProxy();
const agent = new HttpsProxyAgent(proxy.url);
return {
instance: axios.create({
httpsAgent: agent,
timeout: 10000
}),
proxyUrl: proxy.url
};
}
// Mendapatkan statistik proxy
getStats() {
return {
total: this.proxyList.length,
active: this.proxyList.filter(p => p.active).length,
inactive: this.proxyList.filter(p => !p.active).length,
proxies: this.proxyList.map(p => ({
url: p.url.replace(/\/\/.*@/, '//***@'), // Menyembunyikan kredensial
active: p.active,
failures: p.failures
}))
};
}
}
// Menggunakan rotator canggih
const advancedRotator = new AdvancedProxyRotator(proxyList);
async function fetchWithAdvancedRotation(url) {
const { instance, proxyUrl } = await advancedRotator.createAxiosInstance();
try {
const response = await instance.get(url);
advancedRotator.markSuccess(proxyUrl);
return response.data;
} catch (error) {
advancedRotator.markFailure(proxyUrl);
throw error;
}
}
// Pelaporan statistik secara berkala
setInterval(() => {
console.log('Statistik proxy:', advancedRotator.getStats());
}, 30000);
Sistem semacam ini secara otomatis mengecualikan proxy yang tidak berfungsi dari rotasi dan mendistribusikan beban secara merata di antara server aktif. Ini sangat penting saat bekerja dengan volume data yang besar.
Penanganan kesalahan dan otomatisasi pengalihan proxy
Saat bekerja dengan proxy, kesalahan tidak dapat dihindari: timeout, penolakan koneksi, pemblokiran dari server tujuan. Penanganan kesalahan yang tepat dan pengalihan otomatis ke proxy lain meningkatkan keandalan aplikasi.
Contoh implementasi sistem dengan pengulangan otomatis dan pengalihan proxy:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
class ResilientProxyClient {
constructor(proxyList, maxRetries = 3) {
this.proxyList = proxyList;
this.maxRetries = maxRetries;
this.currentProxyIndex = 0;
}
// Mendapatkan proxy berikutnya
getNextProxy() {
const proxy = this.proxyList[this.currentProxyIndex];
this.currentProxyIndex = (this.currentProxyIndex + 1) % this.proxyList.length;
return proxy;
}
// Menentukan jenis kesalahan
isRetryableError(error) {
// Kesalahan yang sebaiknya diulang
const retryableCodes = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED'];
const retryableStatuses = [408, 429, 500, 502, 503, 504];
if (error.code && retryableCodes.includes(error.code)) {
return true;
}
if (error.response && retryableStatuses.includes(error.response.status)) {
return true;
}
return false;
}
// Melakukan permintaan dengan pengulangan otomatis
async request(url, options = {}, attempt = 1) {
const proxyUrl = this.getNextProxy();
const agent = new HttpsProxyAgent(proxyUrl);
const config = {
...options,
httpsAgent: agent,
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
...options.headers
}
};
try {
console.log(`Percobaan ${attempt}/${this.maxRetries} dengan proxy: ${proxyUrl.replace(/\/\/.*@/, '//***@')}`);
const response = await axios.get(url, config);
console.log(`Sukses pada percobaan ${attempt}`);
return response.data;
} catch (error) {
console.error(`Percobaan ${attempt} gagal: ${error.message}`);
// Jika batas pengulangan tercapai
if (attempt >= this.maxRetries) {
console.error(`Batas pengulangan (${this.maxRetries}) tercapai untuk ${url}`);
throw error;
}
// Jika kesalahan tidak dapat diulang
if (!this.isRetryableError(error)) {
console.error(`Kesalahan yang tidak dapat diulang: ${error.message}`);
throw error;
}
// Penundaan eksponensial sebelum pengulangan
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
console.log(`Menunggu ${delay}ms sebelum mencoba lagi...`);
await new Promise(resolve => setTimeout(resolve, delay));
// Pengulangan rekursif dengan proxy berikutnya
return this.request(url, options, attempt + 1);
}
}
// Pemrosesan batch URL dengan penanganan kesalahan
async batchRequest(urls, concurrency = 3) {
const results = [];
const queue = [...urls];
const active = [];
while (queue.length > 0 || active.length > 0) {
// Menjalankan tugas baru hingga mencapai batas paralel
while (active.length < concurrency && queue.length > 0) {
const url = queue.shift();
const promise = this.request(url)
.then(data => ({ url, success: true, data }))
.catch(error => ({ url, success: false, error: error.message }))
.finally(() => {
const index = active.indexOf(promise);
if (index > -1) active.splice(index, 1);
});
active.push(promise);
}
// Menunggu setidaknya satu tugas selesai
if (active.length > 0) {
const result = await Promise.race(active);
results.push(result);
}
}
return results;
}
}
// Menggunakan
const proxyList = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080'
];
const client = new ResilientProxyClient(proxyList, 3);
// Permintaan tunggal
client.request('https://api.example.com/data')
.then(data => console.log('Data:', data))
.catch(error => console.error('Kesalahan akhir:', error.message));
// Pemrosesan batch
const urls = [
'https://api.example.com/data/1',
'https://api.example.com/data/2',
'https://api.example.com/data/3',
'https://api.example.com/data/4',
'https://api.example.com/data/5'
];
client.batchRequest(urls, 3)
.then(results => {
const successful = results.filter(r => r.success).length;
const failed = results.filter(r => !r.success).length;
console.log(`Selesai: ${successful} sukses, ${failed} gagal`);
console.log('Hasil:', results);
});
Implementasi ini mencakup:
- Pengalihan otomatis ke proxy berikutnya saat terjadi kesalahan
- Penundaan eksponensial antara pengulangan (1s, 2s, 4s, 8s, 10s max)
- Menentukan jenis kesalahan untuk pengambilan keputusan tentang pengulangan
- Kontrol paralelisme saat pemrosesan batch
- Logging rinci untuk debugging
Praktik terbaik dan optimasi kinerja
Saat bekerja dengan proxy di aplikasi Node.js, sebaiknya ikuti rekomendasi berikut untuk memastikan stabilitas dan kinerja:
1. Manajemen koneksi
Gunakan kembali agen HTTP daripada membuat yang baru untuk setiap permintaan. Ini mengurangi overhead dalam membangun koneksi:
const { HttpsProxyAgent } = require('https-proxy-agent');
// Buruk: membuat agen untuk setiap permintaan
async function badExample(url) {
const agent = new HttpsProxyAgent(proxyUrl);
return axios.get(url, { httpsAgent: agent });
}
// Baik: menggunakan kembali agen
const agent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
httpsAgent: agent,
httpAgent: agent
});
async function goodExample(url) {
return axiosInstance.get(url);
}
2. Pengaturan timeout
Selalu atur timeout yang wajar untuk mencegah aplikasi menggantung:
const axiosInstance = axios.create({
httpsAgent: agent,
timeout: 10000, // Timeout umum
// Pengaturan detail timeout untuk Got
// timeout: {
// lookup: 1000, // DNS lookup
// connect: 2000, // Koneksi ke proxy
// secureConnect: 2000, // SSL handshake
// socket: 5000, // Ketidakaktifan socket
// response: 3000, // Menunggu byte pertama dari respons
// send: 10000, // Mengirim permintaan
// request: 15000 // Seluruh permintaan
// }
});
3. Kontrol paralelisme
Batasi jumlah permintaan simultan untuk mencegah kelebihan beban:
const pLimit = require('p-limit');
// Pembatasan hingga 5 permintaan simultan
const limit = pLimit(5);
async function processUrls(urls) {
const promises = urls.map(url =>
limit(() => axiosInstance.get(url))
);
return Promise.allSettled(promises);
}
4. Rotasi User-Agent
Kombinasikan rotasi proxy dengan rotasi User-Agent untuk anonimitas yang lebih besar:
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'
];
function getRandomUserAgent() {
return userAgents[Math.floor(Math.random() * userAgents.length)];
}
async function fetchWithRandomUA(url) {
return axiosInstance.get(url, {
headers: {
'User-Agent': getRandomUserAgent()
}
});
}
5. Pemantauan dan logging
Terapkan sistem pemantauan untuk melacak kinerja proxy:
class ProxyMonitor {
constructor() {
this.stats = new Map();
}
recordRequest(proxyUrl, success, responseTime) {
if (!this.stats.has(proxyUrl)) {
this.stats.set(proxyUrl, {
total: 0,
success: 0,
failed: 0,
totalResponseTime: 0,
avgResponseTime: 0
});
}
const stat = this.stats.get(proxyUrl);
stat.total++;
if (success) {
stat.success++;
stat.totalResponseTime += responseTime;
stat.avgResponseTime = stat.totalResponseTime / stat.success;
} else {
stat.failed++;
}
}
getReport() {
const report = [];
this.stats.forEach((stat, proxyUrl) => {
report.push({
proxy: proxyUrl.replace(/\/\/.*@/, '//***@'),
successRate: ((stat.success / stat.total) * 100).toFixed(2) + '%',
avgResponseTime: stat.avgResponseTime.toFixed(0) + 'ms',
total: stat.total,
success: stat.success,
failed: stat.failed
});
});
return report;
}
}
const monitor = new ProxyMonitor();
// Pembungkus untuk permintaan dengan pemantauan
async function monitoredRequest(url, proxyUrl) {
const startTime = Date.now();
try {
const response = await axiosInstance.get(url);
const responseTime = Date.now() - startTime;
monitor.recordRequest(proxyUrl, true, responseTime);
return response.data;
} catch (error) {
const responseTime = Date.now() - startTime;
monitor.recordRequest(proxyUrl, false, responseTime);
throw error;
}
}
// Laporan berkala
setInterval(() => {
console.table(monitor.getReport());
}, 60000);
6. Pemilihan jenis proxy
Pilih jenis proxy tergantung pada tugas:
| Tugas | Jenis yang direkomendasikan | Alasan |
|---|---|---|
| Pengambilan data massal dari data publik | Proxy Data Center | Kecepatan tinggi, harga rendah |
| Bekerja dengan media sosial dan platform yang dilindungi | Proxy residensial | IP nyata, risiko pemblokiran rendah |
| Meniru lalu lintas seluler | Proxy seluler | IP dari operator seluler |
| Bekerja dengan protokol non-standar | Proxy SOCKS5 | Dukungan untuk semua lalu lintas |
Untuk tugas yang memerlukan tingkat anonimitas tinggi dan risiko pemblokiran minimal, disarankan untuk menggunakan proxy residensial. Untuk pengambilan data berkecepatan tinggi dalam jumlah besar, proxy data center sangat cocok.
7. Keamanan kredensial
Jangan pernah menyimpan kredensial proxy dalam kode. Gunakan variabel lingkungan:
// file .env
PROXY_HOST=proxy-server.com
PROXY_PORT=8080
PROXY_USERNAME=your-username
PROXY_PASSWORD=your-password
// Dalam kode
require('dotenv').config();
const proxyUrl = `http://${process.env.PROXY_USERNAME}:${process.env.PROXY_PASSWORD}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
// Atau untuk daftar proxy
const proxyList = process.env.PROXY_LIST.split(',').map(proxy => proxy.trim());
Kesimpulan
Pengaturan proxy di aplikasi Node.js adalah keterampilan penting bagi pengembang yang bekerja dengan pengambilan data, otomatisasi, dan integrasi dengan API eksternal. Dalam panduan ini, kita telah membahas semua cara dasar untuk bekerja dengan proxy: dari pengaturan dasar melalui modul bawaan hingga teknik lanjutan dengan rotasi, penanganan kesalahan, dan pemantauan.
Poin kunci yang perlu diingat:
- Pilih pustaka untuk permintaan HTTP berdasarkan tugas: Axios untuk fleksibilitas, Got untuk proyek TypeScript, node-fetch untuk kompatibilitas dengan API browser
- Gunakan proxy SOCKS5 untuk bekerja dengan protokol non-standar dan fleksibilitas maksimum
- Implementasikan rotasi proxy untuk mendistribusikan beban dan menghindari pemblokiran
- Terapkan sistem penanganan kesalahan dengan pengulangan otomatis dan pengalihan proxy
- Pantau kinerja proxy dan secara otomatis kecualikan yang tidak berfungsi
- Gunakan kembali agen HTTP dan atur timeout yang wajar
- Simpan kredensial dalam variabel lingkungan, bukan dalam kode
Saat memilih proxy untuk aplikasi Node.js Anda, pertimbangkan spesifikasi tugas. Untuk pengambilan data dari platform yang dilindungi dan bekerja dengan API yang sensitif terhadap reputasi IP, disarankan untuk menggunakan proxy residensial — mereka memberikan tingkat anonimitas tinggi dan risiko pemblokiran minimal berkat penggunaan alamat IP nyata dari pengguna rumah.