Kembali ke blog

Pengaturan Proxy di Aplikasi Node.js: Panduan Lengkap dengan Contoh Kode

Panduan rinci untuk mengintegrasikan proxy di Node.js: dari pengaturan dasar hingga teknik lanjutan rotasi IP dan penanganan kesalahan.

📅14 Februari 2026
```html

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.

```