June 4

Почему и как использовать cURL в JavaScript

Если вы разработчик, то освоение cURL — это уже не опция, а необходимость. А когда вы сочетаете cURL с JavaScript, вы получаете мощное сочетание для выполнения сетевых запросов, автоматизации передачи данных и работы с API как профессионал.

В этом руководстве мы покажем, как использовать cURL в JavaScript, рассмотрим несколько методов, реальные примеры и лучшие практики. К концу вы точно будете знать, как эффективно и надежно интегрировать возможности cURL в ваши JavaScript-проекты.

Полезен ли cURL в JavaScript?

cURL — это проверенный временем инструмент командной строки, известный передачей данных по множеству протоколов — HTTP, HTTPS, FTP и другим. Но настоящая магия происходит, когда вы встраиваете функциональность cURL внутрь JavaScript-приложений. Вы сможете:

  • Автоматически парсить сайты
  • Интегрироваться с сложными API
  • Программно скачивать файлы
  • Точно запускать автоматические тесты

Звучит интересно? Погнали!

Настройка окружения

Прежде чем начать, убедитесь, что у вас есть:

  • Node.js (рекомендуется версия 12 и выше)
  • npm (менеджер пакетов Node)
  • Базовые знания асинхронного JavaScript
  • cURL, установленный в системе (для методов с вызовом shell-команд)

Быстрая настройка проекта:

mkdir curl-js-project
cd curl-js-project
npm init -y

Метод 1: Использование Node child_process для запуска cURL-команд

Самый простой способ использовать cURL в JavaScript — запускать shell-команды через Node child_process. Это позволяет напрямую выполнять cURL-запросы.

const { exec } = require('child_process');

function curlRequest(url, options = {}) {
  return new Promise((resolve, reject) => {
    let curlCommand = `curl -s "${url}"`;

    if (options.headers) {
      for (const [key, value] of Object.entries(options.headers)) {
        curlCommand += ` -H "${key}: ${value}"`;
      }
    }

    if (options.method) {
      curlCommand += ` -X ${options.method}`;
    }

    if (options.data) {
      curlCommand += ` -d '${JSON.stringify(options.data)}'`;
    }

    exec(curlCommand, (error, stdout, stderr) => {
      if (error) return reject(new Error(error.message));
      if (stderr) return reject(new Error(stderr));
      try {
        resolve(JSON.parse(stdout));
      } catch {
        resolve(stdout);
      }
    });
  });
}

Плюсы и минусы

  • Плюсы: Быстрая настройка, не требует дополнительных пакетов
  • Минусы: Требуется установленный cURL, возможны уязвимости для внедрения команд (command injection), ограниченная обработка ошибок

Используйте для простых скриптов и быстрых решений. Для более сложных задач — читайте дальше.

Метод 2: Мощь node-libcurl

Хотите больше контроля и лучшую производительность? node-libcurl — это обертка для libcurl в Node.js, которая даёт нативную мощь прямо в вашем коде.

Установка:

npm install node-libcurl

Пример использования:

const { Curl } = require('node-libcurl');

function performRequest(url, options = {}) {
  return new Promise((resolve, reject) => {
    const curl = new Curl();
    curl.setOpt(Curl.option.URL, url);

    if (options.headers) {
      curl.setOpt(
        Curl.option.HTTPHEADER,
        Object.entries(options.headers).map(([k, v]) => `${k}: ${v}`)
      );
    }

    if (options.method === 'POST' && options.data) {
      curl.setOpt(Curl.option.POST, true);
      curl.setOpt(Curl.option.POSTFIELDS, JSON.stringify(options.data));
    }

    curl.setOpt(Curl.option.FOLLOWLOCATION, true);

    curl.on('end', (statusCode, data, headers) => {
      try {
        resolve({ statusCode, data: JSON.parse(data), headers });
      } catch {
        resolve({ statusCode, data, headers });
      }
      curl.close();
    });

    curl.on('error', err => {
      reject(err);
      curl.close();
    });

    curl.perform();
  });
}

Почему node-libcurl?

  • Нативная производительность, без накладных расходов shell
  • Точный контроль над опциями запроса
  • Улучшенная обработка ошибок
    Идеально подходит для приложений, где важна скорость и стабильность.

Метод 3: Используйте request-promise для простых запросов

Если хотите что-то проще, но всё ещё мощное — request-promise отлично подойдёт.

Установка:

npm install request request-promise

Пример:

const rp = require('request-promise');

async function curlLikeRequest(url, options = {}) {
  const requestOptions = {
    uri: url,
    method: options.method || 'GET',
    headers: options.headers || {},
    json: true,
    resolveWithFullResponse: true,
  };

  if (options.data && ['POST', 'PUT'].includes(options.method)) {
    requestOptions.body = options.data;
  }

  if (options.params) {
    requestOptions.qs = options.params;
  }

  try {
    const response = await rp(requestOptions);
    return {
      statusCode: response.statusCode,
      data: response.body,
      headers: response.headers,
    };
  } catch (error) {
    if (error.response) {
      throw {
        statusCode: error.statusCode,
        data: error.response.body,
        headers: error.response.headers,
      };
    }
    throw error;
  }
}

Используйте Axios для современных HTTP-запросов

Axios взлетел по популярности не зря. Это promise-библиотека, которая работает как в браузере, так и в Node.js, и отлично справляется с JSON.

Установка:

npm install axios

Пример использования, имитирующего cURL:

const axios = require('axios');

async function curlWithAxios(url, options = {}) {
  const config = {
    url,
    method: options.method || 'GET',
    headers: options.headers || {},
    timeout: options.timeout || 10000,
  };

  if (options.data) config.data = options.data;
  if (options.params) config.params = options.params;

  try {
    const response = await axios(config);
    return {
      statusCode: response.status,
      data: response.data,
      headers: response.headers,
    };
  } catch (error) {
    if (error.response) {
      throw {
        statusCode: error.response.status,
        data: error.response.data,
        headers: error.response.headers,
      };
    } else if (error.request) {
      throw { message: 'Ответ не получен', request: error.request };
    }
    throw error;
  }
}

Axios поддерживает:

  • Отмену запросов
  • Интерцепторы (например, для авторизации, логирования)
  • Защиту от XSRF на клиенте

Продвинутые советы по обработке ошибок и лучшим практикам

Сетевые запросы могут ломаться — это факт. Поэтому нужно строить устойчивость:

  • Грамотно обрабатывайте HTTP-коды ошибок: реагируйте по-разному на 404, 401, 500
  • Реализуйте повторные попытки с экспоненциальным увеличением задержки, чтобы не нагружать сервер
  • Ведите подробный лог ошибок с деталями запросов и ответов
  • Отслеживайте лимиты по количеству запросов и вовремя снижайте активность
  • Валидируйте ответы API — не доверяйте форме данных

Пример простой функции с повтором запросов:

async function retryRequest(url, retries = 3, delay = 1000) {
  for (let i = 0; i < retries; i++) {
    try {
      return await curlWithAxios(url);
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(res => setTimeout(res, delay * Math.pow(2, i)));
    }
  }
}

Настройка прокси для cURL в JavaScript

Прокси важны для веб-скрапинга, обхода геоограничений или анонимизации запросов.

Через child_process:

const { exec } = require('child_process');

function curlThroughProxy(url, { host, port, username, password }) {
  return new Promise((resolve, reject) => {
    const proxyAuth = username && password ? `${username}:${password}` : '';
    let curlCommand = `curl -s -x ${host}:${port}`;
    if (proxyAuth) curlCommand += ` -U "${proxyAuth}"`;
    curlCommand += ` "${url}"`;

    exec(curlCommand, (error, stdout, stderr) => {
      if (error) return reject(new Error(error.message));
      if (stderr) return reject(new Error(stderr));
      try {
        resolve(JSON.parse(stdout));
      } catch {
        resolve(stdout);
      }
    });
  });
}

Через node-libcurl:

const { Curl } = require('node-libcurl');

function requestViaProxy(url, { host, port, username, password }) {
  return new Promise((resolve, reject) => {
    const curl = new Curl();
    curl.setOpt(Curl.option.URL, url);
    curl.setOpt(Curl.option.PROXY, `${host}:${port}`);
    curl.setOpt(Curl.option.PROXYTYPE, CurlProxy.Http);

    if (username && password) {
      curl.setOpt(Curl.option.PROXYUSERPWD, `${username}:${password}`);
    }

    curl.on('end', (statusCode, data, headers) => {
      try {
        resolve({ statusCode, data: JSON.parse(data), headers });
      } catch {
        resolve({ statusCode, data, headers });
      }
      curl.close();
    });

    curl.on('error', err => {
      reject(err);
      curl.close();
    });

    curl.perform();
  });
}

С Axios и https-proxy-agent:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

async function axiosWithProxy(url, { host, port, username, password }) {
  const proxyUrl = username && password
    ? `http://${username}:${password}@${host}:${port}`
    : `http://${host}:${port}`;

  const httpsAgent = new HttpsProxyAgent(proxyUrl);

  try {
    const response = await axios({ url, method: 'GET', httpsAgent });
    return { statusCode: response.status, data: response.data, headers: response.headers };
  } catch (error) {
    throw error.response
      ? { statusCode: error.response.status, data: error.response.data, headers: error.response.headers }
      : error;
  }
}

Итоги

cURL — это не просто инструмент командной строки, а универсальная мощь, которую можно использовать прямо из JavaScript. Будь то быстрые shell-команды, нативные обертки или современные HTTP-клиенты вроде Axios — освоение этих инструментов выведет ваши проекты на новый уровень.

Не забывайте про надежную обработку ошибок, умные повторные запросы и использование прокси — это сделает ваши приложения гораздо устойчивее. Начинайте экспериментировать и превращайте HTTP-запросы в надежный инструмент своей разработки.