《Axios响应处理:构建完整响应对象与异常处理》
<|begin▁of▁sentence|># 1. 前言
在上一篇文章中,我们实现了处理响应`headers`、并解析获得`headers`对象。接下来,我们就在获取到`headers`对象的基础上,继续实现对响应`data`的处理。
根据上一篇文章中,我们设计的`axios`接口,我们希望`axios`函数能够返回一个`promise`对象,并且能够接收到一个响应对象`response`,其中该响应对象包括:`data`、`status`、`statusText`、`headers`、`config`、`request`。如下:
```typescript
axios({
method: "get",
url: "/api/handleResponse",
}).then((res) => {
console.log(res);
});
```
我们希望`then`函数中得到的`res`对象是这样的:
```json
{
"data": {
"text": "hello world"
},
"status": 200,
"statusText": "OK",
"headers": {
"content-type": "application/json; charset=utf-8",
"date": "Sat, 21 Sep 2019 13:55:54 GMT",
"connection": "close",
"content-length": "17"
},
"config": {
// ...
},
"request": {
// ...
}
}
```
# 2. 需求分析
从需求分析中,我们可以看出,我们需要在`then`函数中拿到一个`response`对象,该对象中不仅包含`data`、`status`、`statusText`、`headers`,还包含我们之前传给`axios`函数的配置对象`config`和我们发送请求的`XMLHttpRequest`对象实例`request`。
所以,我们首先要创建一个`response`对象,该对象包含上面这些属性,然后我们在`onreadystatechange`事件函数中,当`readyState`为`4`的时候,也就是接收到响应的时候,将`response`对象传给`resolve`函数即可。
# 3. 创建响应对象
根据需求,我们创建`src/types/index.ts`文件,并在其中定义`AxiosResponse`接口类型,该类型接口包含`data`、`status`、`statusText`、`headers`、`config`和`request`属性。
```typescript
export interface AxiosResponse {
data: any; // 服务端返回的数据
status: number; // HTTP 状态码
statusText: string; // 状态消息
headers: any; // 响应头
config: AxiosRequestConfig; // 请求配置对象
request: any; // 请求的 XMLHttpRequest 对象实例
}
```
另外,我们`axios`函数返回的是`Promise`对象,我们可以定义一个`AxiosPromise`接口,它继承于`Promise`泛型接口:
```typescript
export interface AxiosPromise extends Promise {}
```
这样的话,当`axios`返回的是`AxiosPromise`类型时,`resolve`函数中的参数就是一个`AxiosResponse`类型。
# 4. 实现逻辑
首先,我们在`src/xhr.ts`中,在`onreadystatechange`事件函数中,如果`readyState`不为 4,则直接返回。
```typescript
if (xhr.readyState !== 4) {
return;
}
```
然后,我们获取到响应`headers`,这个在上一篇文章中已经实现,然后我们再获取到响应`data`、`status`、`statusText`,接着把它们构建成一个`response`对象,然后传给`resolve`函数。
```typescript
const responseHeaders = parseHeaders(xhr.getAllResponseHeaders());
const responseData = xhr.responseText;
const response: AxiosResponse = {
data: responseData,
status: xhr.status,
statusText: xhr.statusText,
headers: responseHeaders,
config,
request: xhr,
};
resolve(response);
```
另外,我们虽然发送了请求,并且也接收到了响应,但是有可能网络异常或者请求超时,这个时候我们应该在`onerror`事件函数和`ontimeout`事件函数中,使用`reject`函数,把错误信息返回。
```typescript
// 处理错误
xhr.onerror = function() {
reject(new Error("Network Error"));
};
// 处理超时
xhr.ontimeout = function() {
reject(new Error(`Timeout of ${config.timeout} ms exceeded`));
};
```
OK,这样我们就实现了对响应`data`的处理,并且还处理了网络异常和请求超时的情况。
# 5. 编写 demo
在 `examples` 目录下创建 `handleResponse`目录,在 `handleResponse`目录下创建 `index.`:
```
< lang="en">
Handle response example
>
```
接着再创建 `app.ts` 作为入口文件:
```typescript
import axios from "../../src/index";
axios({
method: "get",
url: "/api/handleResponse",
})
.then((res) => {
console.log(res);
})
.catch((e) => {
console.log(e);
});
axios({
method: "get",
url: "/api/handleResponse1",
})
.then((res) => {
console.log(res);
})
.catch((e) => {
console.log(e);
});
axios({
method: "get",
url: "/api/handleResponse2",
})
.then((res) => {
console.log(res);
})
.catch((e) => {
console.log(e);
});
setTimeout(() => {
axios({
method: "get",
url: "/api/handleResponse",
timeout: 2000,
})
.then((res) => {
console.log(res);
})
.catch((e) => {
console.log(e);
});
}, 5000);
```
接着在 `server.js` 中添加新的接口路由:
```javascript
// 响应正常
router.get("/api/handleResponse", function(req, res) {
res.json({
text: "hello world",
});
});
// 响应异常
router.get("/api/handleResponse1", function(req, res) {
res.status(500).send("server error");
});
// 响应超时
router.get("/api/handleResponse2", function(req, res) {
setTimeout(() => {
res.json({
text: "hello world",
});
}, 3000);
});
```
最后在根目录下的`index.`中加上启动该`demo`的入口:
```
Handle response
```
# 6. 运行 demo
接着我们在命令行中执行:
```bash
# 同时开启客户端和服务端
npm run server | npm start
```
接着我们打开 `chrome` 浏览器,访问 即可访问我们的 `demo` 了,我们点击 `Handle response`,通过`F12`的 `network` 部分我们可以看到发送的请求,并且`console`中输出:
- 正常响应

- 异常响应

- 超时响应

- 超时设置

OK,这样我们就实现了对响应`data`的处理。
最新文章
- 高效节能汽车冷却系统优化设计
- 2023年智能驾驶、固态电池与车联网三大技术趋势解析
- 电动汽车革命:固态电池与800V快充引领未来出行
- 固态电池突破:能量密度提升40%,快充技术革新电动车未来
- 毫米波雷达助力智能驾驶
- 雷达技术助力智能汽车发展
- 网联自动驾驶技术革新未来出行
- 电动液压助力转向系统:智能驾驶的核心技术解析
- OAT冷却液保护汽车引擎防止过热
- 驾驶员疲劳检测系统实时监控行车安全
- 汽车冷却风扇高效散热保障引擎稳定运行
- 智能座舱与电动化浪潮:车联网时代的汽车科技变革
- 电动化浪潮下:电池技术突破与智能驾驶的未来发展
- 宝马驾驶体验无与伦比的舒适
- 车龄与保养指南:不同阶段养护重点及费用解析
- 电动化与智能化双轮驱动:汽车产业的技术变革与未来趋势
- 激光雷达助力智能汽车发展
- 电动化革命:从电池突破到智能互联的未来出行
- 发动机过热导致汽车无法正常行驶
- 激光雷达:自动驾驶的3D火眼金睛与未来挑战
