Tutorials Logic, IN info@tutorialslogic.com

Axios Library HTTP Requests

Axios Client

Axios is a promise-based HTTP client for browsers and Node.js. It provides request and response interceptors, automatic JSON transformation, configurable instances, timeouts, cancellation through AbortController signals, and a consistent error object. Modern fetch is built into browsers, so Axios is a dependency choice rather than a requirement for AJAX.

After this lesson, you can create a scoped Axios instance, pass query parameters separately from request data, classify Axios errors, and keep interceptors from becoming hidden application logic.

What is Axios?

Axios is a popular, Promise-based HTTP client for both the browser and Node.js. It automatically serializes request bodies to JSON, automatically parses JSON responses, and rejects the Promise for HTTP error status codes - fixing one of the most common fetch() gotchas.

Install via npm: npm install axios, or include via CDN:

Axios GET, POST, PUT, DELETE

Axios GET, POST, PUT, DELETE
// GET - params are serialized automatically
axios.get('/api/users', {
  params: { page: 1, limit: 10, active: true }
})
.then(response => {
  // response.data is already parsed JSON
  console.log(response.data);
  console.log(response.status);    // 200
  console.log(response.headers);  // response headers
});

// POST - body is automatically JSON.stringify'd
axios.post('/api/users', {
  name: 'Alice',
  email: 'alice@example.com'
})
.then(res => console.log('Created:', res.data));

// PUT
axios.put('/api/users/1', { name: 'Alice Updated', email: 'alice@example.com' })
  .then(res => console.log('Updated:', res.data));

// DELETE
axios.delete('/api/users/1')
  .then(res => console.log('Deleted, status:', res.status));

Request Config and Error Handling

Request Config and Error Handling
// Full config object
axios({
  method: 'post',
  url: '/api/login',
  headers: { 'X-Custom-Header': 'value' },
  timeout: 10000,           // 10 seconds
  data: { username: 'alice', password: 'secret' }
})
.then(res => console.log(res.data))
.catch(error => {
  if (error.response) {
    // Server responded with a status outside 2xx
    console.error('HTTP Error:', error.response.status);
    console.error('Data:', error.response.data);
  } else if (error.request) {
    // Request was made but no response received (network error)
    console.error('No response received:', error.request);
  } else {
    // Something went wrong setting up the request
    console.error('Request setup error:', error.message);
  }
});

axios.create() and Interceptors

axios.create() and Interceptors
// Create a reusable Axios instance with defaults
const api = axios.create({
  baseURL: 'https://api.example.com/v1',
  timeout: 8000,
  headers: { 'Accept': 'application/json' }
});

// Request interceptor - runs before every request
api.interceptors.request.use(
  config => {
    // Attach auth token from localStorage
    const token = localStorage.getItem('authToken');
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  error => Promise.reject(error)
);

// Response interceptor - runs after every response
api.interceptors.response.use(
  response => response, // pass through successful responses
  error => {
    if (error.response?.status === 401) {
      // Token expired - redirect to login
      localStorage.removeItem('authToken');
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

// Now use the instance - baseURL and interceptors apply automatically
api.get('/users').then(res => console.log(res.data));
api.post('/posts', { title: 'Hello' }).then(res => console.log(res.data));

Axios vs Fetch Comparison

Feature Axios fetch()
Dependency External library (~14KB) Built-in
Auto JSON stringify Yes Manual
Auto JSON parse Yes (response.data) Manual (res.json())
HTTP error rejection Yes (4xx/5xx reject) No - must check res.ok
Request cancellation CancelToken / AbortController AbortController
Interceptors Built-in Not built-in
Upload progress onUploadProgress Not built-in
Node.js support Yes Node 18+ only

Axios with async/await and Upload Progress

Axios with async/await and Upload Progress
// async/await with Axios
async function createUser(userData) {
  try {
    const { data } = await axios.post('/api/users', userData);
    console.log('New user ID:', data.id);
    return data;
  } catch (error) {
    const msg = error.response?.data?.message || error.message;
    console.error('Create user failed:', msg);
    throw error;
  }
}

// File upload with progress tracking
async function uploadFile(file) {
  const formData = new FormData();
  formData.append('file', file);

  try {
    const { data } = await axios.post('/api/upload', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      onUploadProgress: (progressEvent) => {
        const percent = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        document.getElementById('progress').style.width = `${percent}%`;
        document.getElementById('progress-text').textContent = `${percent}%`;
      }
    });
    console.log('Uploaded:', data.url);
  } catch (err) {
    console.error('Upload failed:', err.message);
  }
}

Client Instance

Create one instance for one API boundary with its base URL, timeout, and stable headers. Keep environment-specific origins in build or deployment configuration. Use the params option for URL query values and data for a JSON request body; this makes the request intent visible and lets Axios perform serialization consistently.

A timeout limits how long the client waits, but it does not prove the server stopped processing a write. Apply the same idempotency rules used for fetch. Use an AbortController signal when the user action or component lifecycle should explicitly cancel the request.

Interceptors

A request interceptor can attach a current authorization credential or correlation header. A response interceptor can normalize a narrow transport concern or coordinate one token-refresh mechanism. Keep business-specific redirects, notifications, and data mutations near the feature that owns them; global interceptors otherwise create surprising side effects for unrelated calls.

Interceptors registered dynamically return an ID that can be ejected. This matters in tests, hot reload, and component-scoped setup, where repeated registration can run the same interceptor multiple times. Avoid retry loops by marking a refresh attempt and excluding the refresh request itself.

Axios Errors

When Axios rejects, error.response indicates that the server replied outside the accepted status range, error.request indicates that a request was made without a usable response, and a setup error has neither. Cancellation is a separate expected case. Classify these branches before choosing a message or retry.

Axios normally rejects non-2xx statuses, unlike fetch, but validateStatus can change that policy. Document any custom policy on the instance because it changes which branch consumers must handle. Do not log the complete configuration object when it may contain credentials or sensitive request data.

Before you move on

Axios Review

4 checks
  • Use a scoped instance for a coherent API boundary.
  • Put query values in params and body values in data.
  • Keep interceptors narrow and eject dynamic registrations.
  • Classify response, request, setup, and cancellation failures.

Client Surprises

  • Creating a new Axios configuration in every component.

    Share a configured API client and keep feature calls focused.
  • Adding notifications in a global interceptor.

    Return a classified failure and let the owning feature choose the UI.
  • Retrying token refresh recursively.

    Use one guarded refresh flow and exclude its own request.

Try this next

Build an API Client

0 of 2 completed

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.