手写一个axios方法
如何实现一个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
处理错误。