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.
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:
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
bodyproperty, which must be a JSON string; manual
JSON.stringifyis 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.okand
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
AbortControllerto 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.stringifyneeded.
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-typedefaults to
application/json.
Configuration Merge Strategy
headers,
params,
metaare shallow‑merged.
If both
dataobjects are plain, they are shallow‑merged; otherwise later config overwrites.
Other fields are overwritten by later config.
Standardization Process
Convert
methodto uppercase, default to
GET.
Merge URL search parameters into
params(params take precedence).
Convert header values to strings and normalize header names.
Invalid
timeoutbecomes
0.
Expose read‑only
rawURL(original URL).
Ensure
paramsand
headersare 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
errorHandlerin the instance configuration.
Standard Service Requests
Request encourages using
ServiceHelperto 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.
Goodme Frontend Team
Regularly sharing the team's insights and expertise in the frontend field
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.