Frontend Development 27 min read

Choosing the Right Frontend Request Library: XHR, Fetch, Axios vs Guming Request

This article reviews frontend HTTP request libraries—XMLHttpRequest, Fetch API, Axios, and Guming’s internal Request—detailing their usage, advantages, drawbacks, core features, request flow, and comparison to help developers choose the most suitable library for their projects.

Goodme Frontend Team
Goodme Frontend Team
Goodme Frontend Team
Choosing the Right Frontend Request Library: XHR, Fetch, Axios vs Guming Request

Introduction

In modern web development, frontend request libraries simplify client‑server data exchange, improve development efficiency and application performance. They encapsulate HTTP request complexity and provide a consistent API, allowing developers to focus on business logic. The author previously used XMLHttpRequest, Fetch API, and Axios, each with its own strengths.

Common Request Handling Methods

XMLHttpRequest – Traditional Asynchronous Communication

XMLHttpRequest (XHR) is one of the earliest JavaScript async communication techniques. It enables partial page updates without a full reload. Example GET request:

<code>const xhr = new XMLHttpRequest();
const url = 'https://api.example.com/data';
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();</code>

Pros: Works in all browsers, including legacy versions.

Cons: Verbose API, no Promise support, lower readability and maintainability.

Fetch API – Native Asynchronous Web API

Fetch is a modern Promise‑based API that offers a cleaner way to make network requests. Simple GET example:

<code>fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));</code>

Pros: Promise‑based, concise, supports streaming for large files.

Cons: Requires manual handling of HTTP status codes and JSON serialization; no built‑in request cancellation.

Axios – Feature‑Rich HTTP Request Library

Axios is a Promise‑based library for browsers and Node.js, providing automatic JSON conversion and interceptors. GET example:

<code>import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));</code>

Pros: Simple API, automatic JSON handling, request/response interceptors, request cancellation.

Cons: Adds an external dependency compared with Fetch.

Request – Guming Internal Standardized Request Library

After joining Guming, the author adopted the internal Request library, which standardizes request handling across teams. Basic GET usage:

<code>import { request } from '@guming/request';

const http = request.create();
http.get('https://api.example.com/data')
  .then(res => console.log(res.data));</code>

Pros: Standardized API, no external dependencies, small bundle, comprehensive features.

Cons: Smaller community support than Axios.

What Is the Request Library?

Request is Guming’s internal HTTP request library designed to standardize and simplify frontend data requests. Its core advantages are a unified API, multi‑environment compatibility, and built‑in capabilities such as retry, request deduplication, and caching.

Core Features

Standardized API and configuration across browsers, mini‑programs, and Node.

Multi‑environment compatibility (XHR in browsers, Axios‑based in Node).

Built‑in generic abilities: retry, deduplication, caching.

Intuitive API, low learning curve.

No external dependencies, lightweight.

Request Flow

Initialize request (merge config, set headers, timeout, etc.).

Apply request interceptors (e.g., add auth token).

Check cache; return cached data if hit.

Send actual network request if cache miss.

Detect errors (network or server).

Retry according to strategy.

Handle unrecoverable errors.

Apply response interceptors.

Cache response if needed.

Check for error status codes.

Transform response data.

Return final data to caller.

Request flow diagram:

Request flow diagram
Request flow diagram

Comparison with Other Libraries

While simple requests may appear similar, Fetch, Axios, and Request differ in capabilities for complex scenarios.

Fetch API

Advantages: No third‑party package, Promise‑based, supports streaming. Drawbacks: No automatic JSON handling, special error handling, lacks built‑in timeout (requires AbortController) and request cancellation.

Basic Usage

fetch returns a Promise; you must call

res.json()

to parse JSON.

Headers and Parameters

fetch uses the

body

property, which must be a JSON string; manual

JSON.stringify

is required.

<code>const handleSendFetch = async () => {
  const res = await fetch('https://api.example.com/data', {
    method: 'POST',
    body: JSON.stringify({ page: { pageSize: 10, pageNo: 1 } }),
    headers: {
      'content-type': 'application/json',
      Authorization: 'Bearer eyJhbGciOiJSUzI1xxxx',
    },
  });
  const data = await res.json();
  console.log(data);
};</code>

Error Handling

fetch does not reject on HTTP error status; you must inspect

res.ok

and

res.status

.

<code>const handleSendFetch = async () => {
  const res = await fetch('https://api.example.com/data', { method: 'POST', ... });
  if (!res.ok) {
    throw new Error(`HTTP error! status: ${res.status}`);
  }
  const data = await res.json();
  console.log(data);
};</code>

Timeout Handling

Use

AbortController

to abort after a timeout.

<code>const controller = new AbortController();
const options = { method: 'POST', signal: controller.signal, body: JSON.stringify({ ... }) };
const promise = fetch('https://api.example.com/data', options);
setTimeout(() => controller.abort(), 5000);
promise.then(res => res.json()).then(data => console.log(data)).catch(err => console.dir(err));</code>

Axios

Axios provides a Promise‑based API with automatic JSON conversion, configurable timeout, and interceptors.

Core Features (official)

Works in browsers (XHR) and Node (http).

Supports Promise API.

Request/response interceptors.

Automatic request/response data transformation.

Request cancellation.

Timeout handling.

Nested query‑parameter serialization.

Automatic handling of JSON, multipart/form‑data, and URL‑encoded forms.

Upload/download progress information.

Node bandwidth limiting.

FormData and Blob compatibility.

Built‑in XSRF protection.

Basic Usage

Axios offers dedicated methods such as

axios.get()

,

axios.post()

, etc., and automatically parses JSON responses.

Headers and Parameters

GET parameters are passed via

params

; POST data via

data

. No manual

JSON.stringify

needed.

Error Handling

<code>axios.get('https://api.example.com/data')
  .catch(error => {
    if (error.response) {
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      console.log(error.request);
    } else {
      console.log('Error', error.message);
    }
    console.log(error.config);
  });</code>

Timeout Handling

<code>axios({
  url: 'https://api.example.com/data',
  method: 'GET',
  timeout: 5000,
});</code>

Request/Response Interceptors

<code>axios.interceptors.request.use(config => {
  // modify config before request is sent
  return config;
}, error => Promise.reject(error));

axios.interceptors.response.use(response => {
  // handle response data
  return response;
}, error => Promise.reject(error));</code>

Request Cancellation

<code>const controller = new AbortController();
axios.get('https://api.example.com/datar', { signal: controller.signal })
  .then(response => { /* ... */ });
controller.abort(); // cancel request</code>

Request (Guming)

Core Features

Standardized API and configuration, multi‑environment support, extensible design.

Built‑in generic abilities: retry, deduplication, caching.

Presets for common logic.

Simple, friendly API.

No external dependencies, small bundle.

Basic Usage

<code>import { request } from '@guming/request';

const http = request.create();
http({ url: '/api/example/1' }).then(res => console.log(res));
http.post('/api/example/2', { foo: 'bar' }).then(res => console.log(res));
</code>

Headers

Headers are normalized to lowercase strings;

content-type

defaults to

application/json

.

Configuration Merge Strategy

headers

,

params

,

meta

are shallow‑merged.

If both

data

objects are plain, they are shallow‑merged; otherwise later config overwrites.

Other fields are overwritten by later config.

Standardization Process

Convert

method

to uppercase, default to

GET

.

Merge URL search parameters into

params

(params take precedence).

Convert header values to strings and normalize header names.

Invalid

timeout

becomes

0

.

Expose read‑only

rawURL

(original URL).

Ensure

params

and

headers

are objects.

<code>http({
  url: '/a?x=1&y=2',
  params: { x: 3 },
  method: 'post',
  headers: { 'x-custom': 999, 'content-type': 'application/json' },
  timeout: -1,
});
// Normalized to:
// {
//   url: '/a',
//   rawURL: '/a?x=1&y=2',
//   params: { x: '3', y: '2' },
//   method: 'POST',
//   headers: { 'x-custom': '999', 'content-type': 'application/json' },
//   timeout: 0,
// }
</code>

Request/Response Interception

<code>import { request } from '@guming/request';

const http = request.create();

http.tap('request', config => {
  config.url = `https://example.com${config.url}`;
}).tap('response', response => {
  // handle response
}).tap('error', error => {
  // handle error
});

http.get('/api/1');
</code>

Request Cancellation

<code>const http = request.create();
const promise = http.get('/example');
promise.then(res => console.log(res));
setTimeout(() => promise.abort(), 1000); // cancel after 1 s
</code>

Error Handling

Use

catch()

on the returned Promise.

Use

tap('error', …)

to intercept all errors.

Provide a custom

errorHandler

in the instance configuration.

Standard Service Requests

Request encourages using

ServiceHelper

to create team‑wide service definitions, reducing over‑encapsulation.

<code>import { ServiceHelper, request } from '@guming/request';

const http = request.create();
const serviceHelper = new ServiceHelper({ http });

const service = {
  commit: serviceHelper.define({ url: '/example/commit', method: 'post' }),
};

service.commit({ user: 'Alice', age: 18 }).then(res => console.log(res));
</code>

Event Listening

Requests expose

.on()

and

.off()

for events such as upload/download progress.

<code>http.get('/example')
  .on('downloadProgress', p => console.log(p))
  .then(res => console.log(res));
</code>

Comparison Summary

Fetch is suitable for simple HTTP calls, Axios offers richer configuration and flexibility, while Request provides a balanced feature set with strong emphasis on team‑wide standardization and minimal external dependencies. Community support is strongest for Fetch and Axios; Request’s community is internal.

Why Choose Request?

Standardization reduces over‑customization, a lean API (13 config items) lowers learning cost, and preset functionality enables reusable business logic. A lightweight, internally maintained library offers better control over bundle size and performance compared with external solutions.

frontendaxiosfetchHTTPrequestxmlhttprequestlibrary-comparison
Goodme Frontend Team
Written by

Goodme Frontend Team

Regularly sharing the team's insights and expertise in the frontend field

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.