使用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.前言

本篇文章主要做一些項目的起手,編寫代碼實現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 方法;datapostpatch 等類型請求的數據,放到 request body 中的;paramsgethead 等類型請求的數據,拼接到 urlquery 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.htmlapp.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 ,通過F12network 部分我們可以看到成功發送到了一條請求,並在 response 中看到了服務端返回的數據。

至此,我們就實現了一個簡單的請求發送,並編寫了相關的 demo。但是現在存在一些問題:我們傳入的 params 數據並沒有用,也沒有拼接到 url 上;我們對 request body 的數據格式、請求頭 headers 也沒有做處理;另外我們雖然從網絡層面收到了響應的數據,但是我們代碼層面也並沒有對響應的數據做處理。那么下面一篇文章,我們就來解決這些問題。

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM