基于Typescript和Axios的接口请求管理

基于Typescript和Axios的接口请求管理“这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战” 本文主要介绍基于TS和AXIOS的接口请求封装 思路 请求拦截 在请求头添加一些参数,例如token,uid等 判断用户登录状态,如果

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

本文主要介绍基于TS和AXIOS的接口请求封装

思路

  • 请求拦截

    • 在请求头添加一些参数,例如token,uid等
    • 判断用户登录状态,如果没有登录,直接跳转登录
    • 处理请求数据转换发送请求的数据格式,json→urlencoded (可选的)
  • 响应拦截

    • 判断后端响应的业务状态码,进行不同的处理

      • 例如用户登录状态过期,直接跳转登录
      • 统一的报错提示

先把套路化的代码写出来:

import axios, {
    AxiosInstance,
    AxiosResponse,
    AxiosRequestConfig,
    AxiosError
} from 'axios'
export default abstract class HttpClient {
    protected readonly instance: AxiosInstance

    public constructor(baseURL = '/api', timeout = 1000 * 120) {
        this.instance = axios.create({
            baseURL,
            timeout
        })
        // 1. 请求拦截器
        this._initializeRequestInterceptor()
        // 2. 响应拦截器
        this._initializeResponseInterceptor()
    }
    private _initializeRequestInterceptor = () => {
        this.instance.interceptors.request.use(
            this._handleRequest,
            this._handleError
        )
    }
    private _handleRequest = (config: AxiosRequestConfig) => {}
   
    private _initializeResponseInterceptor = () => {
        this.instance.interceptors.response.use(
            this._handleResponse,
            this._handleError
        )
    }
    private _handleResponse = (response: AxiosResponse) => {}
    protected _handleError = (error: AxiosError) => Promise.reject(error)
}

简单说一下上面的代码,我们创建了一个用于请求接口的HttpClient类,在constructor中定义了baseURL和超时时间timeout,同时定义了请求拦截方法和响应拦截方法。

至此,发起一个接口的流程如下:

  1. 发送请求之前,调用请求拦截
  2. 发送接口,network出现请求
  3. 接口响应,调用响应拦截
  4. 响应给前端程序,执行对应的逻辑

请求拦截

下面开始详细的逻辑,请求拦截的时候,可以做的事情如下:

  • 在请求头添加一些参数,例如token,uid等
  • 判断用户登录状态,如果没有登录,直接跳转登录
  • 处理请求数据转换发送请求的数据格式,json→urlencoded (可选的)
     private _handleRequest = (config: AxiosRequestConfig) => {
        //1. 添加自定义请求头
        config.headers['Authorization'] = 'my token'
        config.headers['mobile'] = 'my mobile'
        //2. 判断是否登录(判断是否有toke)
        
        //3. 转化数据格式
        config.data = qs.stringify(config.data)
        return config
    }

响应拦截

得到了响应之后,处理如下:

  1. 判断后端响应的业务状态码,进行不同的处理
    • 如果用户登录状态过期,直接跳转登录
    • 统一的报错提示
  2. 保存token
 // 响应拦截器
    private _handleResponse = (response: AxiosResponse) => {
        const { data, headers } = response

        //1.--处理响应的token,保存token
        const token = headers['authorization']
        if (token) {
            this._saveToken(token)
        }
       
        //2. --处理响应码,这里try-catch一下,如果后端有的接口没有返回code,直接返回
        try {
            const code = data.code,
            message = data.desc || data.msg
            const isSucceed = this._handleResCode(code, message, url)
            if (isSucceed) {
                return Promise.resolve(data)
            } else {
                return Promise.reject(message)
            }
        } catch (error) {
            return Promise.resolve(data)
        }
       
    }
    //保存token
    private _saveToken(token: string) {
        const USER = getModule(UserModule)
        USER.setToken(token)
    }
    private _handleResCode(code: number, message: string, url: string) {
        if (code === 0) {
            // 请求成功
            return true
        } else if (code===4000) {
            // token失效,跳回登录界面
            Vue.prototype.$message.error('身份信息过期,请重新登陆')
            router.push({ name: 'login' })
            return false
        } else {
            // 其他情况,统统提示message信息
            Vue.prototype.$message.error(message)
            return false
        }
    }

使用httpClient.ts定义请求

建议请求相关的文件定义在@/api目录下面,目录如下

httpClient.ts
user.ts
uti.ts

在对应的文件中定义请求,注意事项

  1. 所有请求类需要继承HttpClient类,HttpClient做了一些统一拦截统一处理请求及响应的工作
  2. 请求响应的数据需要提供类型,类型定义在@/types/xxx文件中,一个模块对应一个文件。只有提供了类型,才会有代码提示
import HttpClient from './HttpClient'
import { AlarmItemType } from '../types/test'
import { BaseResType } from '../types/index'

class UtilApi extends HttpClient {
   //例如后台返回的响应 res={code:xxx,data:xxx,token:xxx,desc:xxx}
    //首先需要定义 res.data 的类型 即get的第一个参数 AlarmItemType
    //然后需要定义整个响应的类型 即 BaseResType<AlarmItemType>
    public getAlarmById = (id: string) =>
        this.instance.get<AlarmItemType, BaseResType<AlarmItemType>>(
            `/realtime/alarms/queryByAlarmId/${id}`
        )
}

export const UTIL_API = new UtilApi()

在组件中请求接口

在需要发送请求的组件中键入请求模块的关键字,例如USER_API,如果安装了插件TypeScript Importer,就会有相应的模块导入提示,此时输入回车即可导入相应的模块。

<template>
    <section>请求数据:{{ alarmData }}</section>
</template>

<script lang="ts"> import { UTIL_API } from '@/api/utilApi' import { Vue, Component } from 'vue-property-decorator' @Component({ components: {} }) export default class TestRequest extends Vue { alarmData = {} async getAlarmData() { const res = await UTIL_API.getAlarmById('alarmIdc7e9bd47') if (res.code == 0) { this.$message.success('请求成功') this.alarmData = res.data } } mounted() { this.getAlarmData() } } </script>
<style lang="scss" scoped></style>

今天的文章基于Typescript和Axios的接口请求管理分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23319.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注