markdown
# 自制简易 Axios 库示例
**Axios** 是一个基于 `Promise` 的 HTTP 库,它简化了浏览器与 Node.js 中的 AJAX 请求处理。若想从零开始,利用原生 **XMLHttpRequest (XHR)** 结合 `Promise` 封装一个简化的 Axios 版本,可参考以下代码示例:
```javascript
class Axios {
constructor() {
// 初始化 XMLHttpRequest 实例
this.xhr = new XMLHttpRequest();
}
// 发送 GET 请求
get(url, config = {}) {
return new Promise((resolve, reject) => {
this.xhr.open('GET', url, true);
// 配置请求头
if (config.headers) {
Object.keys(config.headers).forEach(key =>
this.xhr.setRequestHeader(key, config.headers[key])
);
}
this.xhr.onload = () => {
if (this.xhr.status >= 200 && this.xhr.status < 300) {
resolve(this.xhr.responseText);
} else {
reject(new Error(`Request failed with status code ${this.xhr.status}`));
}
};
this.xhr.onerror = () => reject(new Error('Network Error'));
this.xhr.send();
});
}
// 发送 POST 请求
post(url, data = {}, config = {}) {
return new Promise((resolve, reject) => {
this.xhr.open('POST', url, true);
// 设置默认 Content-Type 及额外请求头
this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
if (config.headers) {
Object.keys(config.headers).forEach(key =>
this.xhr.setRequestHeader(key, config.headers[key])
);
}
this.xhr.onload = () => {
if (this.xhr.status >= 200 && this.xhr.status < 300) {
resolve(this.xhr.responseText);
} else {
reject(new Error(`Request failed with status code ${this.xhr.status}`));
}
};
this.xhr.onerror = () => reject(new Error('Network Error'));
// 数据转换,示例中为简单的 URL 编码
this.xhr.send(this.transformData(data));
});
}
// 数据转换示例方法
transformData(data) {
return Object.keys(data).map(key =>
`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`
).join('&');
}
}
// 使用示例
const myAxios = new Axios();
myAxios.get('https://api.example.com/data')
.then(response => console.log(JSON.parse(response)))
.catch(error => console.error(error));
myAxios.post('https://api.example.com/submit', { key: 'value' })
.then(response => console.log(JSON.parse(response)))
.catch(error => console.error(error));
注意: 此示例较为基础,未涵盖 Axios 完整功能,如 JSON 自动处理、多种 HTTP 方法支持、请求取消、拦截器等高级特性。特别是 POST 请求的数据处理部分,根据 Content-Type
可能需要调整 transformData
方法以适应不同的数据格式(例如直接发送 JSON 字符串)。