当前位置 : 主页 > 网络编程 > JavaScript >

基于Typescript与Axios的接口请求管理详解

来源:互联网 收集:自由互联 发布时间:2022-04-19
目录 思路 请求拦截 响应拦截 使用httpClient.ts定义请求 在组件中请求接口 总结 本文主要介绍基于TS和AXIOS的接口请求封装 思路 请求拦截 在请求头添加一些参数,例如token,uid等 判断用户
目录
  • 思路
  • 请求拦截
  • 响应拦截
  • 使用httpClient.ts定义请求
  • 在组件中请求接口
  • 总结

本文主要介绍基于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. 响应给前端程序,执行对应的逻辑

请求拦截

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

  1. 在请求头添加一些参数,例如token,uid等
  2. 判断用户登录状态,如果没有登录,直接跳转登录
  3. 处理请求数据转换发送请求的数据格式,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
    }

响应拦截

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

  • 判断后端响应的业务状态码,进行不同的处理
    • 如果用户登录状态过期,直接跳转登录
    • 统一的报错提示
  • 保存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的接口请求管理的文章就介绍到这了,更多相关Typescript与Axios接口请求内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

上一篇:JavaScript 上传文件限制参数案例详解
下一篇:没有了
网友评论