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.前言
本篇文章主要做一些項目的起手,編寫代碼實現axios
最基本的操作,如下:
axios({
method: 'get',
url: '/base/get',
params: {
a: 1,
b: 2
}
})
主要目的是跑通整個流程,為后續的開發做准備。
2.創建入口文件
我們在src
目錄下,先創建一個 index.ts
文件,作為整個庫的入口文件,然后我們先定義一個 axios
方法,並把它導出,如下:
// src/index.ts
function axios(config) {
}
export default axios
在上面代碼中,我們需要給 config
參數定義了一種接口類型。我們創建一個 types
目錄,在下面創建一個 index.ts
文件,作為我們項目中公用的類型定義文件。
// types/index.ts
export interface AxiosRequestConfig {
url: string
method?: string
data?: any
params?: any
}
其中,url
為請求的地址,必選屬性;而其余屬性都是可選屬性。method
是請求的 HTTP 方法;data
是 post
、patch
等類型請求的數據,放到 request body
中的;params
是 get
、head
等類型請求的數據,拼接到 url
的 query string
中的。
為了讓 method
只能傳入合法的字符串,我們定義一種字符串字面量類型 Method
:
export type Method = 'get' | 'GET'
| 'delete' | 'Delete'
| 'head' | 'HEAD'
| 'options' | 'OPTIONS'
| 'post' | 'POST'
| 'put' | 'PUT'
| 'patch' | 'PATCH'
然后回到 src/index.ts
,我們引入 AxiosRequestConfig
類型,作為 config
的參數類型,如下:
// src/index.ts
import { AxiosRequestConfig } from './types'
function axios(config: AxiosRequestConfig) {
}
export default axios
OK,入口文件axios
核心對象創建成功!
3. 封裝原生 ajax 操作
axios
的核心功能就是發送請求,所以我們必須將原生的ajax
操作進行封裝,后面將用它來發送所有請求。
我們在 src
目錄下創建一個 xhr.ts
文件,我們導出一個 xhr
方法,它接受一個 config
參數,類型也是 AxiosRequestConfig
類型。
// src/xhr.ts
export default function xhr(config: AxiosRequestConfig): void {
const { data = null, url, method = 'get' } = config
const request = new XMLHttpRequest()
request.open(method.toUpperCase(), url, true)
request.send(data)
}
我們首先通過解構賦值的語法從 config
中拿到對應的屬性值賦值給我的變量,並且還定義了一些默認值,因為在 AxiosRequestConfig
接口的定義中,有些屬性是可選的。
接着我們實例化了一個 XMLHttpRequest
對象,然后調用了它的 open
方法,傳入了對應的一些參數,最后調用 send
方法發送請求。
4. 引入 xhr 模塊
編寫好了 xhr
模塊,我們就需要在 index.ts
中去引入這個模塊,如下:
// src/index.ts
import { AxiosRequestConfig } from './types'
import xhr from './xhr'
function axios(config: AxiosRequestConfig): void {
xhr(config)
}
export default axios
OK,基本的發送請求代碼完成,接下來,我們可以寫一個簡單的demo,來驗證一下我們剛才編寫的axios
對象能否使用。
5. 編寫demo
demo
分為客戶端和服務端:客戶端用來發送請求;服務端用來響應請求。
5.1 編寫服務端server
服務端采用express
庫編寫,在 server
目錄下創建 server.js
文件:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const router = express.Router();
// 使用body-parser中間件
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
router.get('/api/base/get', function (req, res) {
res.json({
msg: `hello world`
})
})
app.use(router)
const port = process.env.PORT || 3000
module.exports = app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}, Ctrl+C to stop`)
})
5.2 編寫客戶端examples
首先在項目根目錄下創建 index.html
,作為所有 demo
的入口文件。
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ts-axios examples</title>
</head>
<body>
<h1>ts-axios examples</h1>
<ul>
<li><a href="examples/base">Base</a></li>
</ul>
</body>
</html>
然后在 examples
目錄下創建 base
目錄,作為本篇文章的 demo 目錄,在該目錄下再創建 index.html
和 app.ts
文件
index.html
文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Baseexample</title>
</head>
<body>
<script src="/__build__/base.js"></script>
</body>
</html>
app.ts
文件如下:
import axios from '../../src/index'
axios({
method: 'get',
url: '/api/base/get',
params: {
a: 1,
b: 2
}
})
5.3 運行demo
我們在命令行中執行:
# 同時開啟客戶端和服務端
npm run server | npm start
其中:
npm run server
相當於執行了 node server/server.js
,會開啟我們的服務端。
npm start
會開啟我們的客戶端。
接着我們打開 chrome 瀏覽器,訪問 http://localhost:8000/ 即可訪問我們的 demo 了,我們點擊 Base
,通過F12
的 network
部分我們可以看到成功發送到了一條請求,並在 response
中看到了服務端返回的數據。
至此,我們就實現了一個簡單的請求發送,並編寫了相關的 demo。但是現在存在一些問題:我們傳入的 params
數據並沒有用,也沒有拼接到 url
上;我們對 request body
的數據格式、請求頭 headers
也沒有做處理;另外我們雖然從網絡層面收到了響應的數據,但是我們代碼層面也並沒有對響應的數據做處理。那么下面一篇文章,我們就來解決這些問題。
(完)