基于ts重构axios
ustbhuangyi 老师的 基于TypeScript从零重构axios学习记录。
知识点
TypeScript 常用语法:
基础类型 、 函数 、 变量声明 、 接口 、 类 、 泛型 、 类型推新 、 高级类型
axios js库:
项目脚手架 、 基础功能实现 、 异常情况处理 、 接口扩展 、 拦截器实现 、 配置化实现 、 取消功能实现 、 其他功能实现等等
主要工具:Jest 、 TSLint 、 Commitizen 、 Prettier 、 RollupJS 、 Semantic release
基本语法
需求分析
Features
- 在浏览器使用 XMLHttpRequest 对象通讯
- 支持 Promise API
- 支持请求和响应的拦截器
- 支持请求数据和响应数据的转换
- 支持请求的取消
- JSON数据的自动转换
- 客户端防止 XSRF
基于 XMLHttpRequest 编写基本请求代码
处理请求数据:url/body/headers
src/types/index.ts
1 | export type Method = 'get' | 'GET' | 'delete' | 'Delete' | 'head' | 'HEAD' | 'options' | 'OPTIONS' | 'post' | 'POST' | 'put' | 'PUT' | 'patch' | 'PATCH' |
src/xhr.ts
1 | import { AxiosRequestConfig } from './types' |
src/index.ts
1 | import { AxiosRequestConfig } from './types' |
工具类
data.ts
1 | import { isPlainObject } from "./util"; |
headers.ts
1 | import { isPlainObject } from "./util" |
url.ts
1 | import { isDate, isPlainObject } from './util' |
处理响应数据
定义响应接口
types/index
1 | export interface AxiosResponse { |
处理 headers 的数据
helpers/header.ts
1 | export function processHeaders(headers: any, data: any): any { |
处理 响应data
helpers/data.ts
1 | export function transformResponse(data: any): any { |
修改 xhr, 返回一个 Promise
xhr.ts
1 | import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from './types' |
)
.replace(/%2C/ig, ',')
.replace(/%20/g, '+')
.replace(/%5B/ig, '[')
.replace(/%5D/ig, ']')
}
export function buildURL(url: string, params?: any): string {
if (!params) {
return url
}
const parts: string[] = []
Object.keys(params).forEach(key => {
const val = params[key]
if (val === null || typeof val === 'undefined') {
return
}
let values = []
if (Array.isArray(val)) {
values = val
key += '[]'
} else {
values = [val]
}
values.forEach(val => {
if (isDate(val)) {
val = val.toISOString()
} else if (isPlainObject(val)) {
val = JSON.stringify(val)
}
parts.push( `${encode(key)}=${encode(val)}` )
})
})
let serializedParams = parts.join(‘&’)
if (serializedParams) {
const markIndex = url.indexOf('#')
if (markIndex !== -1) {
url = url.slice(0, markIndex)
}
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
}
return url
}
1 |
|
处理响应数据
定义响应接口
types/index
1 | export interface AxiosResponse { |
处理 headers 的数据
helpers/header.ts
1 | export function processHeaders(headers: any, data: any): any { |
处理 响应data
helpers/data.ts
1 | export function transformResponse(data: any): any { |
修改 xhr, 返回一个 Promise
xhr.ts
1 | import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from './types' |