如何实现一个axios函数呢,我们可以用原生 XMLHttpRequest 来实现一个简易版的 axios,如下:
function axios(config) {
return new Promise((resolve, reject) => {
const { method = 'GET', url, data, headers = {}, timeout = 0 } = config;
const xhr = new XMLHttpRequest();
// 设置请求方法和URL
xhr.open(method, url, true);
// 设置请求头
Object.keys(headers).forEach(key => {
xhr.setRequestHeader(key, headers[key]);
});
// 设置超时
xhr.timeout = timeout;
// 处理响应
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
try {
if (xhr.status >= 200 && xhr.status < 300) {
resolve({
data: JSON.parse(xhr.responseText),
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders()),
config: config,
request: xhr
});
} else {
reject({
status: xhr.status,
statusText: xhr.statusText,
data: xhr.responseText,
config: config,
request: xhr
});
}
} catch (error) {
reject({
status: xhr.status,
statusText: xhr.statusText,
data: xhr.responseText,
config: config,
request: xhr,
error: error.message
});
}
}
};
// 处理网络错误
xhr.onerror = function() {
reject(new Error('Network Error'));
};
// 处理超时
xhr.ontimeout = function() {
reject(new Error(`Request timed out after ${timeout}ms`));
};
// 发送请求
xhr.send(data ? JSON.stringify(data) : null);
});
}
// 辅助函数:解析响应头
function parseHeaders(headersString) {
const headers = {};
if (!headersString) return headers;
headersString.split('\r\n').forEach(header => {
const [key, value] = header.split(': ');
if (key) {
headers[key] = value;
}
});
return headers;
}
// 使用示例
axios({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/posts',
headers: {
'Authorization': 'Bearer your-token'
},
timeout: 5000
})
.then(response => console.log(response))
.catch(error => console.error(error));
axios实现说明:
概述
axios 是一个封装了 XMLHttpRequest 的函数,用于发送 HTTP 请求。它返回一个 Promise,使得异步操作更加简洁和易于处理。
参数
config:一个对象,包含请求的各种配置项。method:请求方法,默认为'GET'。url:请求的 URL。data:请求体数据,通常用于POST或PUT请求。headers:请求头,默认为空对象{}。timeout:请求超时时间,默认为0(表示没有超时限制)。
1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
2. 设置请求方法和 URL
xhr.open(method, url, true);
method:请求方法(如'GET'、'POST'等)。url:请求的 URL。true:表示请求是异步的。
3. 设置请求头
Object.keys(headers).forEach(key => {
xhr.setRequestHeader(key, headers[key]);
});
遍历 headers 对象的键,使用 setRequestHeader 方法设置每个请求头。
4. 设置超时
xhr.timeout = timeout;
设置请求的超时时间(单位为毫秒)。
5. 处理响应
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
try {
if (xhr.status >= 200 && xhr.status < 300) {
resolve({
data: JSON.parse(xhr.responseText),
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders()),
config: config,
request: xhr
});
} else {
reject({
status: xhr.status,
statusText: xhr.statusText,
data: xhr.responseText,
config: config,
request: xhr
});
}
} catch (error) {
reject({
status: xhr.status,
statusText: xhr.statusText,
data: xhr.responseText,
config: config,
request: xhr,
error: error.message
});
}
}
};
onreadystatechange:当xhr的readyState属性改变时触发。xhr.readyState === 4:表示请求已完成。xhr.status >= 200 && xhr.status < 300:表示请求成功。- 解析响应体
xhr.responseText并将其转换为 JSON 对象。 - 调用
resolve,将成功响应的数据返回。
- 解析响应体
- 其他状态码:表示请求失败,调用
reject,将错误信息返回。 try-catch:捕获解析 JSON 时可能发生的错误,并调用reject。
6. 处理网络错误
xhr.onerror = function() {
reject(new Error('Network Error'));
};
当发生网络错误时,调用 reject,返回一个包含错误信息的 Error 对象。
7. 处理超时
xhr.ontimeout = function() {
reject(new Error(`Request timed out after ${timeout}ms`));
};
当请求超时时,调用 reject,返回一个包含超时信息的 Error 对象。
8. 发送请求
xhr.send(data ? JSON.stringify(data) : null);
- 如果
data存在,则将其转换为 JSON 字符串并发送。 - 否则,发送
null。
9. 辅助函数:解析响应头
function parseHeaders(headersString) {
const headers = {};
if (!headersString) return headers;
headersString.split('\r\n').forEach(header => {
const [key, value] = header.split(': ');
if (key) {
headers[key] = value;
}
});
return headers;
}
headersString:从xhr.getAllResponseHeaders()获取的响应头字符串。- 将响应头字符串按行分割,每行再按
:分割,提取键值对并存入headers对象中。
10. 使用示例
axios({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/posts',
headers: {
'Authorization': 'Bearer your-token'
},
timeout: 5000
})
.then(response => console.log(response))
.catch(error => console.error(error));
- 发送一个
GET请求到指定的 URL。 - 设置请求头
Authorization。 - 设置请求超时时间为 5000 毫秒。
- 使用
then处理成功响应,使用catch处理错误。










