使用Typescript重构axios(六)——实现基础功能:获取响应数据
0. 系列文章
1.使用Typescript重构axios(一)——写在最前面
2.使用Typescript重构axios(二)——项目起手,跑通流程
3.使用Typescript重构axios(三)——实现基础功能:处理get请求url参数
4.使用Typescript重构axios(四)——实现基础功能:处理post请求参数
5.使用Typescript重构axios(五)——实现基础功能:处理请求的header
6.使用Typescript重构axios(六)——实现基础功能:获取响应数据
7.使用Typescript重构axios(七)——实现基础功能:处理响应header
8.使用Typescript重构axios(八)——实现基础功能:处理响应data
9.使用Typescript重构axios(九)——异常处理:基础版
10.使用Typescript重构axios(十)——异常处理:增强版
11.使用Typescript重构axios(十一)——接口扩展
12.使用Typescript重构axios(十二)——增加参数
13.使用Typescript重构axios(十三)——让响应数据支持泛型
14.使用Typescript重构axios(十四)——实现拦截器
15.使用Typescript重构axios(十五)——默认配置
16.使用Typescript重构axios(十六)——请求和响应数据配置化
17.使用Typescript重构axios(十七)——增加axios.create
18.使用Typescript重构axios(十八)——请求取消功能:总体思路
19.使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式
20.使用Typescript重构axios(二十)——请求取消功能:实现第一种使用方式
21.使用Typescript重构axios(二十一)——请求取消功能:添加axios.isCancel接口
22.使用Typescript重构axios(二十二)——请求取消功能:收尾
23.使用Typescript重构axios(二十三)——添加withCredentials属性
24.使用Typescript重构axios(二十四)——防御XSRF攻击
25.使用Typescript重构axios(二十五)——文件上传下载进度监控
26.使用Typescript重构axios(二十六)——添加HTTP授权auth属性
27.使用Typescript重构axios(二十七)——添加请求状态码合法性校验
28.使用Typescript重构axios(二十八)——自定义序列化请求参数
29.使用Typescript重构axios(二十九)——添加baseURL
30.使用Typescript重构axios(三十)——添加axios.getUri方法
31.使用Typescript重构axios(三十一)——添加axios.all和axios.spread方法
32.使用Typescript重构axios(三十二)——写在最后面(总结)
1. 前言
在之前的文章中,不管是get
请求还是post
请求都已经可以正常发出了,并且在浏览器的F12
中也都能正确的看到返回的数据了,但这仅仅是在浏览器中利用开发者工具看到返回的数据,而在代码中我们还是无法拿到返回的数据,我们期望的使用方式应该是如下样子的:
axios({
method: 'post',
url: '/api/getResponse',
data: {
a: 1,
b: 2
}
}).then((res) => {
console.log(res)
})
我们期望能够拿到服务端响应的数据,并且支持 Promise
链式调用的方式。
2. 响应数据接口定义
我们先来分析下,我们都想要拿到服务端给我们响应哪些数据:首先最主要的服务端返回的数据data
不能少,其次,例如HTTP 状态码status
,状态消息 statusText
,响应头 headers
、请求配置对象 config
以及请求的 XMLHttpRequest
对象实例 request
,这些信息我们也都想拿到,基于此,我们先在src/types/index.ts
中定义一下服务端响应的数据接口类型AxiosResponse
,如下:
export interface AxiosResponse {
data: any; // 服务端返回的数据
status: number; // HTTP 状态码
statusText: string; // 状态消息
headers: any; // 响应头
config: AxiosRequestConfig; // 请求配置对象
request: any; // 请求的 XMLHttpRequest 对象实例
}
另外,我们还期望axios
函数能够返回一个 Promise
对象,以满足我们想要的链式调用,那么我们可以定义一个 AxiosPromise
接口,它继承于 Promise<AxiosResponse>
这个泛型接口:
export interface AxiosPromise extends Promise<AxiosResponse> {
}
这样的话,当 axios
返回的是 AxiosPromise
类型,那么 resolve
函数中的参数就是一个 AxiosResponse
类型。
对于一个 AJAX
请求的响应,我们在发送请求的时候还可以通过设置 XMLHttpRequest
对象的responseType
属性来指定它响应数据的类型responseType
(responseType的MDN介绍),于是,我们可以给之前定义好的 AxiosRequestConfig
类型添加一个可选属性responseType
,添加后如下:
export interface AxiosRequestConfig {
url: string;
method?: Method;
headers?: any;
data?: any;
params?: any;
responseType?: XMLHttpRequestResponseType;
}
responseType
的类型是一个 XMLHttpRequestResponseType
类型,它的定义是 "" | "arraybuffer" | "blob" | "document" | "json" | "text"
字符串字面量类型。
3. 获取响应
定义好响应数据的接口类型后,我们就可以来写获取响应的逻辑了。我们知道,一个完整的AJAX
流程大致分为4步:
创建XMLHttpRequest异步对象;
配置请求参数;
发送请求;
注册事件,获取响应数据
之前在src/xhr.ts
中我们已经完成了前3步,那么接下来我们就实现第4步:
import { AxiosPromise, AxiosRequestConfig, AxiosResponse } from "./types";
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const { data = null, url, method = "get", headers, responseType } = config;
// 1.创建XMLHttpRequest异步对象
const request = new XMLHttpRequest();
// 2.配置请求参数
request.open(method.toUpperCase(), url, true);
Object.keys(headers).forEach(name => {
if (data === null && name.toLowerCase() === "content-type") {
delete headers[name];
}
request.setRequestHeader(name, headers[name]);
});
if (responseType) {
request.responseType = responseType;
}
// 3.发送请求
request.send(data);
// 4.注册事件,拿到响应信息
request.onreadystatechange = function handleLoad() {
if (request.readyState !== 4) {
return;
}
const responseHeaders = request.getAllResponseHeaders();
const responseData =
responseType && responseType !== "text"
? request.response
: request.responseText;
const response: AxiosResponse = {
data: responseData,
status: request.status,
statusText: request.statusText,
headers: responseHeaders,
config,
request
};
resolve(response);
};
});
}
这里,我们还判断了如果 config
中配置了 responseType
,我们要把它设置到 request.responseType
中。
另外,当 responseType
没有设置或者设置为text
时,响应数据存在于request.responseText
,其余情况,响应数据存在于request.response
,所以我们添加了这行代码:
const responseData = responseType && responseType !== "text"? request.response: request.responseText;
最后,在 onreadystatechange
事件函数中,我们构造了 AxiosResponse
类型的 reponse
对象,并把它 resolve
出去。
修改了 xhr
函数,我们同样也要对应修改 axios
函数:
// src/index.ts
function axios(config: AxiosRequestConfig): AxiosPromise {
processConfig(config)
return xhr(config)
}
OK,获取响应就已经完成了,接下来,我们就可以编写demo
来测试下效果怎么样。
4. 编写demo
在 examples
目录下创建 getResponse
目录,在 getResponse
目录下创建 index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>getResponse demo</title>
</head>
<body>
<script src="/__build__/getResponse.js"></script>
</body>
</html>
接着再创建 app.ts
作为入口文件:
import axios from "../../src/index";
axios({
method: "post",
url: "/api/getResponse",
data: {
a: 1,
b: 2
}
}).then(res => {
console.log(res);
});
axios({
method: "post",
url: "/api/getResponse",
responseType: "json",
data: {
a: 3,
b: 4
}
}).then(res => {
console.log(res);
});
接着在 server/server.js
添加新的接口路由:
router.post("/api/getResponse", function(req, res) {
res.json(req.body);
});
最后在根目录下的index.html
中加上启动该demo
的入口:
<li><a href="examples/getResponse">getResponse</a></li>
OK,我们在命令行中执行:
# 同时开启客户端和服务端
npm run server | npm start
接着我们打开 chrome
浏览器,访问 http://localhost:8000/ 即可访问我们的 demo
了,我们点击 getResponse
,通过F12
的控制台我们可以看到:两条请求的响应信息都已经被打印出来了,并且第一条请求我们没有指定responseType
属性,它默认为text
,打印出来的data
数据就是字符串类型,而第二条请求我们指定了responseType: "json"
,打印出来的data
数据就是json
类型的。
5. 遗留问题
从上图中我们还看到,打印出来的headers
变成了字符串类型,并不是我们之前设置的对象类型,而且如果返回的data
是一个json
字符串,我们还应该给它转换成对象类型的。那么后面我们就来做这两件事情。
(完)
使用Typescript重构axios(六)——实现基础功能:获取响应数据的更多相关文章
- 使用Typescript重构axios(三)——实现基础功能:处理get请求url参数
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(四)——实现基础功能:处理post请求参数
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(五)——实现基础功能:处理请求的header
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(七)——实现基础功能:处理响应header
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(八)——实现基础功能:处理响应data
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(九)——异常处理:基础版
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(十六)——请求和响应数据配置化
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(十八)——请求取消功能:总体思路
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
随机推荐
- spring boot参数验证
必须要知道 简述 JSR303/JSR-349,hibernate validation,spring validation 之间的关系 JSR303 是一项标准,JSR-349 是其的升级版本,添加 ...
- CSS样式手册
字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 {font-style: obl ...
- 【CJOJ】为了博多
Description 做了个噩梦,梦见我的 n 把刀到60级会二次变身,变成一个 对推6图有xi点贡献,刷大阪城有yi点贡献 的刀,于是要把刀分成两队一队刷大阪城另一队推6图 . 但是有m对兄弟刀在 ...
- Qt+VC2010+glew环境安装配置
Qt的源码及预编译安装包在 Qt Archive下载,http://download.qt.io/archive/qt/, 目前最新的是Qt5,其中和Qt4不同的是,Qt5多了个QOpenGLWidg ...
- linux系统定时发送邮件
Linux Centos7系统下利用自带的mail发送邮件服务 简介 本章分为五部分. 第一部分是基于虚拟机下的CentOS 7环境定时发送邮件: 第二部分是基于在阿里云购买的CentOS 7服务器环 ...
- 《深入理解Java虚拟机》-----第9章 类加载及执行子系统的案例与实战
概述 在Class文件格式与执行引擎这部分中,用户的程序能直接影响的内容并不太多, Class文件以何种格式存储,类型何时加载.如何连接,以及虚拟机如何执行字节码指令等都是由虚拟机直接控制的行为,用户 ...
- burp插件之xssValidator
0x01 安装环境 Phantomjs 下载:http://phantomjs.org/download.html 下载后配置环境变量,把bin目录下的这个exe加入环境变量 xssValidator ...
- JSON:JSON对象和JSON数组混排的复杂字符串
在java中的一个好用的JSON工具包:net.sf.json.JSONObject 和 net.sf.json.JSONArray 一 解析JSON对象和JSON数组类型混排的复杂字符串 举个例子: ...
- The Mininum Function Value (luoguP2085 最小函数值)
Background\text{Background}Background 1. CSDN's been upgraded today. There's one MORE ad for each pa ...
- [POJ2248] Addition Chains 迭代加深搜索
Addition Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5454 Accepted: 2923 ...