Home » Использование Axios в чистом JavaScript: руководство для начинающих
Использование Axios в чистом JavaScript: руководство для начинающих

Использование Axios в чистом JavaScript: руководство для начинающих

Axios — это мощная HTTP-библиотека для JavaScript, которая превратилась в фактический стандарт для работы с API. Если вы настраиваете сервер, создаете административные панели или разрабатываете мониторинг инфраструктуры, то без качественного HTTP-клиента никуда. Axios предоставляет все необходимые инструменты: интерсепторы, автоматическое преобразование JSON, timeout’ы, отмену запросов и многое другое. В этой статье мы разберем, как максимально эффективно использовать Axios в чистом JavaScript без фреймворков — от базовых запросов до продвинутых техник автоматизации.

Как работает Axios под капотом

Axios построен поверх XMLHttpRequest в браузере и http-модуля в Node.js. Основное преимущество перед встроенным fetch() — это богатые возможности конфигурации и обработки ошибок из коробки. Библиотека использует систему промисов, но с дополнительными возможностями отмены запросов через AbortController.

Внутри Axios реализован паттерн interceptor, который позволяет перехватывать и модифицировать запросы/ответы на лету. Это особенно полезно для добавления токенов авторизации, логирования или обработки ошибок на глобальном уровне.

Быстрая установка и базовая настройка

Для начала работы с Axios есть несколько способов подключения:

// Через CDN (для тестирования)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

// Через npm (рекомендуется для production)
npm install axios

// Через yarn
yarn add axios

Базовая конфигурация для серверных задач:

// Создание экземпляра с базовыми настройками
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json',
    'User-Agent': 'ServerBot/1.0'
  }
});

// Глобальные настройки для всех запросов
axios.defaults.timeout = 10000;
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;

Практические примеры использования

Базовые HTTP-операции

// GET-запрос для получения статистики сервера
async function getServerStats() {
  try {
    const response = await axios.get('/api/server/stats');
    console.log('CPU Usage:', response.data.cpu);
    console.log('Memory Usage:', response.data.memory);
    return response.data;
  } catch (error) {
    console.error('Error fetching server stats:', error.message);
    throw error;
  }
}

// POST-запрос для создания нового пользователя
async function createUser(userData) {
  try {
    const response = await axios.post('/api/users', userData, {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    return response.data;
  } catch (error) {
    if (error.response.status === 409) {
      console.error('User already exists');
    }
    throw error;
  }
}

// PUT-запрос для обновления конфигурации
async function updateConfig(configData) {
  const response = await axios.put('/api/config', configData);
  return response.data;
}

// DELETE-запрос для удаления логов
async function cleanupLogs(olderThan) {
  const response = await axios.delete(`/api/logs?older_than=${olderThan}`);
  return response.data;
}

Продвинутые техники для серверных задач

// Система мониторинга с интерсепторами
const monitoringAPI = axios.create({
  baseURL: 'https://monitoring.example.com',
  timeout: 15000
});

// Интерсептор для логирования всех запросов
monitoringAPI.interceptors.request.use(
  config => {
    console.log(`[${new Date().toISOString()}] ${config.method.toUpperCase()} ${config.url}`);
    return config;
  },
  error => {
    console.error('Request interceptor error:', error);
    return Promise.reject(error);
  }
);

// Интерсептор для автоматической повторной аутентификации
monitoringAPI.interceptors.response.use(
  response => response,
  async error => {
    if (error.response?.status === 401) {
      console.log('Token expired, refreshing...');
      try {
        const newToken = await refreshAuthToken();
        error.config.headers.Authorization = `Bearer ${newToken}`;
        return axios.request(error.config);
      } catch (refreshError) {
        console.error('Token refresh failed:', refreshError);
        // Redirect to login or handle accordingly
      }
    }
    return Promise.reject(error);
  }
);

Обработка ошибок и таймаутов

Правильная обработка ошибок критически важна для серверных приложений:

// Комплексная обработка ошибок
async function robustAPICall(url, data = null) {
  try {
    const config = {
      timeout: 10000,
      retry: 3,
      retryDelay: 1000
    };
    
    const response = await axios.post(url, data, config);
    return response.data;
    
  } catch (error) {
    if (error.code === 'ECONNABORTED') {
      console.error('Request timeout');
    } else if (error.response) {
      // Сервер ответил с ошибкой
      console.error(`Server error: ${error.response.status} - ${error.response.data}`);
    } else if (error.request) {
      // Запрос был отправлен, но ответа нет
      console.error('No response received');
    } else {
      // Ошибка в настройке запроса
      console.error('Request setup error:', error.message);
    }
    
    throw error;
  }
}

// Реализация retry-логики
async function withRetry(fn, maxRetries = 3, delay = 1000) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      
      console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms`);
      await new Promise(resolve => setTimeout(resolve, delay));
      delay *= 2; // Exponential backoff
    }
  }
}

Автоматизация и массовые операции

// Массовая проверка статуса серверов
async function checkServerHealth(serverList) {
  const promises = serverList.map(server => {
    return axios.get(`${server.url}/health`, {
      timeout: 5000,
      validateStatus: status => status < 500
    }).then(response => ({
      server: server.name,
      status: 'healthy',
      responseTime: response.headers['x-response-time']
    })).catch(error => ({
      server: server.name,
      status: 'unhealthy',
      error: error.message
    }));
  });
  
  const results = await Promise.allSettled(promises);
  return results.map(result => result.value);
}

// Отправка уведомлений в Slack/Discord
async function sendAlert(message, webhookUrl) {
  try {
    await axios.post(webhookUrl, {
      text: message,
      channel: '#alerts',
      username: 'ServerBot'
    });
  } catch (error) {
    console.error('Failed to send alert:', error.message);
  }
}

// Автоматическое развертывание через API
async function deployService(serviceName, version) {
  const deploymentData = {
    service: serviceName,
    version: version,
    timestamp: new Date().toISOString()
  };
  
  try {
    const response = await axios.post('/api/deploy', deploymentData, {
      timeout: 60000, // Долгие операции требуют большего таймаута
      headers: {
        'X-Deploy-Token': process.env.DEPLOY_TOKEN
      }
    });
    
    console.log(`Deployment started: ${response.data.deploymentId}`);
    return response.data;
  } catch (error) {
    console.error('Deployment failed:', error.response?.data || error.message);
    throw error;
  }
}

Сравнение с альтернативными решениями

Характеристика Axios Fetch API XMLHttpRequest Node.js http
Размер библиотеки ~45KB Встроенный Встроенный Встроенный
Поддержка промисов ✅ Из коробки ✅ Нативно ❌ Нужен wrapper ❌ Callbacks
Автоматический JSON ✅ Да ❌ Ручное ❌ Ручное ❌ Ручное
Интерсепторы ✅ Да ❌ Нет ❌ Нет ❌ Нет
Отмена запросов ✅ Да ✅ AbortController ✅ abort() ✅ destroy()
Поддержка таймаутов ✅ Встроенная ✅ С AbortController ✅ timeout свойство ✅ setTimeout

Интеграция с другими инструментами

Axios отлично интегрируется с различными инструментами администрирования:

// Интеграция с PM2 для мониторинга процессов
const pm2 = require('pm2');

async function getProcessStats() {
  return new Promise((resolve, reject) => {
    pm2.list((err, processes) => {
      if (err) reject(err);
      
      const stats = processes.map(proc => ({
        name: proc.name,
        status: proc.pm2_env.status,
        cpu: proc.cpu,
        memory: proc.memory
      }));
      
      resolve(stats);
    });
  });
}

// Отправка метрик в Grafana/Prometheus
async function sendMetrics(metrics) {
  try {
    await axios.post('http://localhost:9090/api/v1/write', metrics, {
      headers: {
        'Content-Type': 'application/x-protobuf',
        'X-Prometheus-Remote-Write-Version': '0.1.0'
      }
    });
  } catch (error) {
    console.error('Failed to send metrics:', error.message);
  }
}

// Интеграция с Docker API
async function getContainerStats() {
  try {
    const response = await axios.get('http://localhost:2375/containers/json', {
      params: { all: true }
    });
    
    return response.data.map(container => ({
      id: container.Id.substring(0, 12),
      name: container.Names[0],
      status: container.State,
      image: container.Image
    }));
  } catch (error) {
    console.error('Docker API error:', error.message);
    return [];
  }
}

Продвинутые возможности и хитрости

// Создание пула соединений для высокой нагрузки
const https = require('https');
const http = require('http');

const httpsAgent = new https.Agent({
  keepAlive: true,
  maxSockets: 50
});

const httpAgent = new http.Agent({
  keepAlive: true,
  maxSockets: 50
});

const optimizedAxios = axios.create({
  httpsAgent,
  httpAgent,
  timeout: 30000
});

// Кэширование запросов
const cache = new Map();

axios.interceptors.request.use(config => {
  if (config.method === 'get') {
    const cached = cache.get(config.url);
    if (cached && Date.now() - cached.timestamp < 60000) {
      return Promise.resolve(cached.data);
    }
  }
  return config;
});

axios.interceptors.response.use(response => {
  if (response.config.method === 'get') {
    cache.set(response.config.url, {
      data: response,
      timestamp: Date.now()
    });
  }
  return response;
});

// Middleware для rate limiting
class RateLimiter {
  constructor(maxRequests = 100, timeWindow = 60000) {
    this.maxRequests = maxRequests;
    this.timeWindow = timeWindow;
    this.requests = [];
  }
  
  async checkLimit() {
    const now = Date.now();
    this.requests = this.requests.filter(time => now - time < this.timeWindow);
    
    if (this.requests.length >= this.maxRequests) {
      const waitTime = this.timeWindow - (now - this.requests[0]);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    this.requests.push(now);
  }
}

const rateLimiter = new RateLimiter(10, 60000);

axios.interceptors.request.use(async config => {
  await rateLimiter.checkLimit();
  return config;
});

Практические скрипты для автоматизации

#!/usr/bin/env node
// Скрипт для автоматического бэкапа через API

const axios = require('axios');
const fs = require('fs');
const path = require('path');

async function createBackup() {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const backupName = `backup-${timestamp}`;
  
  try {
    console.log('Starting backup creation...');
    
    // Инициация бэкапа
    const { data } = await axios.post('/api/backup', {
      name: backupName,
      compression: 'gzip',
      incremental: false
    });
    
    const backupId = data.id;
    console.log(`Backup initiated: ${backupId}`);
    
    // Ожидание завершения
    let status = 'running';
    while (status === 'running') {
      await new Promise(resolve => setTimeout(resolve, 5000));
      
      const statusResponse = await axios.get(`/api/backup/${backupId}/status`);
      status = statusResponse.data.status;
      
      console.log(`Backup status: ${status}`);
    }
    
    if (status === 'completed') {
      // Скачивание бэкапа
      const downloadResponse = await axios.get(`/api/backup/${backupId}/download`, {
        responseType: 'stream'
      });
      
      const filePath = path.join(__dirname, 'backups', `${backupName}.tar.gz`);
      const writer = fs.createWriteStream(filePath);
      
      downloadResponse.data.pipe(writer);
      
      return new Promise((resolve, reject) => {
        writer.on('finish', () => {
          console.log(`Backup saved: ${filePath}`);
          resolve(filePath);
        });
        writer.on('error', reject);
      });
    } else {
      throw new Error(`Backup failed with status: ${status}`);
    }
    
  } catch (error) {
    console.error('Backup failed:', error.message);
    process.exit(1);
  }
}

// Запуск с обработкой ошибок
createBackup().catch(console.error);

Полезные факты и нестандартные применения

Axios можно использовать не только для REST API, но и для:

  • GraphQL запросов — просто отправляйте POST с query в теле
  • Работы с WebDAV — поддерживает методы PROPFIND, MKCOL и другие
  • Тестирования API — интеграция с Jest, Mocha для автотестов
  • Proxy-серверов — встроенная поддержка HTTP/HTTPS прокси
  • Мониторинга SSL-сертификатов — проверка срока действия через HTTPS-запросы

Интересная статистика: согласно данным npm, Axios скачивается более 20 миллионов раз в неделю, что делает его одной из самых популярных JavaScript-библиотек. Библиотека активно развивается, с регулярными обновлениями безопасности.

Возможности для автоматизации и DevOps

Axios открывает множество возможностей для автоматизации:

  • CI/CD интеграция — триггеры деплоя, проверка статуса сборки
  • Мониторинг инфраструктуры — health checks, сбор метрик
  • Автоматические бэкапы — по расписанию через cron
  • Нотификации — интеграция с Slack, Telegram, email
  • Управление конфигурацией — обновление настроек через API

Для развертывания таких автоматизированных решений идеально подходят VPS-серверы, которые предоставляют необходимые ресурсы и гибкость настройки. Если вам нужна платформа для экспериментов с API и автоматизацией, рекомендую присмотреться к аренде VPS для легких задач или выделенный сервер для более ресурсоемких проектов.

Заключение и рекомендации

Axios — это не просто HTTP-клиент, а мощный инструмент для построения надежных серверных приложений. Его преимущества особенно ярко проявляются при работе с микросервисами, API интеграциями и задачами автоматизации.

Рекомендации по использованию:

  • Используйте экземпляры axios.create() для разных API с собственными настройками
  • Всегда настраивайте timeout’ы для продакшн-среды
  • Реализуйте retry-логику для критичных запросов
  • Используйте интерсепторы для централизованного логирования и обработки ошибок
  • Не забывайте про rate limiting при работе с внешними API
  • Кэшируйте результаты GET-запросов там, где это уместно

Axios подходит для любых задач — от простых скриптов мониторинга до сложных систем оркестрации. Его надежность и богатый функционал делают его незаменимым инструментом в арсенале любого системного администратора или DevOps-инженера.

Полезные ссылки для дальнейшего изучения:


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

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked