Skip to content

Commit

Permalink
typescript-axios
Browse files Browse the repository at this point in the history
  • Loading branch information
csxiaoyaojianxian committed Jan 1, 2020
1 parent 32fb806 commit d80e2fc
Show file tree
Hide file tree
Showing 263 changed files with 53,105 additions and 2,133 deletions.
1 change: 1 addition & 0 deletions 18-TypeScript/axios/ts-axios-doc/.gitignore → 18-TypeScript/axios/docs/.gitignore
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea/
.DS_Store
node_modules/
dist
2 changes: 1 addition & 1 deletion 18-TypeScript/axios/ts-axios-doc/README.md → 18-TypeScript/axios/docs/README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ TypeScript 从零实现 axios 文档教材
首先 clone 本项目:

```bash
git clone https://git.imooc.com/coding-330/ts-axios-doc.git
git clone https://github.com/Suremotoo/ts-axios-doc.git
```

进入 `ts-axios-doc` 目录后安装项目依赖:
Expand Down
5 changes: 5 additions & 0 deletions 18-TypeScript/axios/docs/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const ghpages = require('gh-pages');

ghpages.publish('dist', function (err) {
debugger
});
142 changes: 142 additions & 0 deletions 18-TypeScript/axios/docs/docs/.vuepress/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
module.exports = {
base: '/test/ts/',
dest: 'dist',
title: 'TypeScript 从零实现 axios',
description: '学习使用 TypeScript 从零实现 axios 库',
themeConfig: {
editLinks: false,
docsDir: 'docs',
nav: [],
sidebar: [
{
title: '初识 TypeScript',
collapsable: false,
children: [
['chapter1/', 'Introduction'],
'chapter1/install',
'chapter1/start'
]
},
{
title: 'TypeScript 常用语法',
collapsable: false,
children: [
'chapter2/type',
'chapter2/declare',
'chapter2/interface',
'chapter2/class',
'chapter2/function',
'chapter2/generic',
'chapter2/inference',
'chapter2/advance'
]
},
{
'title': 'ts-axios 项目初始化',
collapsable: false,
children: [
'chapter3/require',
'chapter3/init',
'chapter3/base'
]
},
{
'title': 'ts-axios 基础功能实现',
collapsable: false,
children: [
'chapter4/url',
'chapter4/data',
'chapter4/header',
'chapter4/response',
'chapter4/response-header',
'chapter4/response-data'
]
},
{
'title': 'ts-axios 异常情况处理',
collapsable: false,
children: [
'chapter5/error',
'chapter5/enhance'
]
},
{
'title': 'ts-axios 接口扩展',
collapsable: false,
children: [
'chapter6/extend',
'chapter6/overload',
'chapter6/generic'
]
},
{
'title': 'ts-axios 拦截器实现',
collapsable: false,
children: [
'chapter7/interceptor'
]
},
{
'title': 'ts-axios 配置化实现',
collapsable: false,
children: [
'chapter8/merge',
'chapter8/transform',
'chapter8/create'
]
},
{
'title': 'ts-axios 取消功能实现',
collapsable: false,
children: [
'chapter9/cancel'
]
},
{
'title': 'ts-axios 更多功能实现',
collapsable: false,
children: [
'chapter10/withCredentials',
'chapter10/xsrf',
'chapter10/upload-download',
'chapter10/auth',
'chapter10/validateStatus',
'chapter10/paramsSerializer',
'chapter10/baseURL',
'chapter10/static'
]
},
{
'title': 'ts-axios 单元测试',
collapsable: false,
children: [
'chapter11/preface',
'chapter11/jest',
'chapter11/helpers',
'chapter11/requests',
'chapter11/headers',
'chapter11/instance',
'chapter11/interceptor',
'chapter11/mergeConfig',
'chapter11/cancel',
'chapter11/more'
]
},
{
'title': 'ts-axios 部署与发布',
collapsable: false,
children: [
'chapter12/build-deploy',
'chapter12/demo'
]
},
{
'title': '课程总结',
collapsable: false,
children: [
'chapter13/summary'
]
}
]
}
}
File renamed without changes
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 初识 TypeScript

TypeScript 作为 JavaScript 语言的超级,它为 JavaScript 添加了可选择的类型标注,大大增强了代码的可读性和可维护性。同时,它提供最新和不断发展的 JavaScript 特性,能让我们建立更健壮的组件。
TypeScript 作为 JavaScript 语言的超集,它为 JavaScript 添加了可选择的类型标注,大大增强了代码的可读性和可维护性。同时,它提供最新和不断发展的 JavaScript 特性,能让我们建立更健壮的组件。

## TypeScript 的特点

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ console.log(greeter(user))

最后,让我们使用类来改写这个例子。 TypeScript 支持 JavaScript 的新特性,比如支持基于类的面向对象编程。

让我们创建一个 `Student` 类,它带有一个构造函数和一些公共字段。因为类的字段包含了接口所需要的字段,所以他们能很好的兼容。
让我们创建一个 `User` 类,它带有一个构造函数和一些公共字段。因为类的字段包含了接口所需要的字段,所以他们能很好的兼容。

还要注意的是,我在类的声明上会注明所有的成员变量,这样比较一目了然。

Expand Down
97 changes: 97 additions & 0 deletions 18-TypeScript/axios/docs/docs/chapter10/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# HTTP 授权

## 需求分析

HTTP 协议中的 [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) 请求 header 会包含服务器用于验证用户代理身份的凭证,通常会在服务器返回 401 Unauthorized 状态码以及 WWW-Authenticate 消息头之后在后续请求中发送此消息头。

axios 库也允许你在请求配置中配置 `auth` 属性,`auth` 是一个对象结构,包含 `username``password` 2 个属性。一旦用户在请求的时候配置这俩属性,我们就会自动往 HTTP 的 请求 header 中添加 `Authorization` 属性,它的值为 `Basic 加密串`
这里的加密串是 `username:password` base64 加密后的结果。

```typescript
axios.post('/more/post', {
a: 1
}, {
auth: {
username: 'Yee',
password: '123456'
}
}).then(res => {
console.log(res)
})
```

## 代码实现

首先修改一下类型定义。

`types/index.ts`

```typescript
export interface AxiosRequestConfig {
// ...
auth?: AxiosBasicCredentials
}

export interface AxiosBasicCredentials {
username: string
password: string
}
```

接着修改合并规则,因为 auth 也是一个对象格式,所以它的合并规则是 `deepMergeStrat`

`core/mergeConfig.ts`

```typescript
const stratKeysDeepMerge = ['headers', 'auth']
```

然后修改发送请求前的逻辑。

`core/xhr.ts`

```typescript
const {
/*...*/
auth
} = config

if (auth) {
headers['Authorization'] = 'Basic ' + btoa(auth.username + ':' + auth.password)
}
```

## demo 编写

```typescript
axios.post('/more/post', {
a: 1
}, {
auth: {
username: 'Yee',
password: '123456'
}
}).then(res => {
console.log(res)
})
```

另外,我们在 `server.js` 中对于这个路由接口写了一段小逻辑:

```javascript
router.post('/more/post', function(req, res) {
const auth = req.headers.authorization
const [type, credentials] = auth.split(' ')
console.log(atob(credentials))
const [username, password] = atob(credentials).split(':')
if (type === 'Basic' && username === 'Yee' && password === '123456') {
res.json(req.body)
} else {
res.end('UnAuthorization')
}
})
```

注意,这里我们需要安装第三方库 `atob` 实现 base64 串的解码。

至此,`ts-axios` 支持了 HTTP 授权功能,用户可以通过配置 auth 对象实现自动在请求 header 中添加 `Authorization` 属性。下一节课我们来实现自定义合法状态码功能。
74 changes: 74 additions & 0 deletions 18-TypeScript/axios/docs/docs/chapter10/baseURL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# baseURL

## 需求分析

有些时候,我们会请求某个域名下的多个接口,我们不希望每次发送请求都填写完整的 url,希望可以配置一个 `baseURL`,之后都可以传相对路径。如下:

```typescript
const instance = axios.create({
baseURL: 'https://some-domain.com/api'
})

instance.get('/get')

instance.post('/post')
```

我们一旦配置了 `baseURL`,之后请求传入的 `url` 都会和我们的 `baseURL` 拼接成完整的绝对地址,除非请求传入的 `url` 已经是绝对地址。

## 代码实现

首先修改一下类型定义。

`types/index.ts`

```typescript
export interface AxiosRequestConfig {
// ...
baseURL?: string
}
```

接下来实现 2 个辅助函数。

`helpers/url.ts`

```typescript
export function isAbsoluteURL(url: string): boolean {
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}

export function combineURL(baseURL: string, relativeURL?: string): string {
return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}
```

最后我们来调用这俩个辅助函数。

`core/dispatchRequest.ts`

```typescript
function transformURL(config: AxiosRequestConfig): string {
let { url, params, paramsSerializer, baseURL } = config
if (baseURL && !isAbsoluteURL(url!)) {
url = combineURL(baseURL, url)
}
return buildURL(url!, params, paramsSerializer)
}
```

## demo 编写

```typescript
const instance = axios.create({
baseURL: 'https://img.mukewang.com/'
})

instance.get('5cc01a7b0001a33718720632.jpg')

instance.get('https://img.mukewang.com/szimg/5becd5ad0001b89306000338-360-202.jpg')
```

这个 demo 非常简单,我们请求了慕课网的 2 张图片,注意当第二个请求 `url` 已经是绝对地址的时候,我们并不会再去拼接 `baseURL`

至此,`ts-axios` 就实现了 `baseURL` 的配置功能,接下来我们来实现 `ts-axios` 的静态方法扩展。
Loading

0 comments on commit d80e2fc

Please sign in to comment.