欢迎来到代码驿站!

JavaScript代码

当前位置:首页 > 网页前端 > JavaScript代码

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

时间:2022-05-08 10:04:58|栏目:JavaScript代码|点击:

本文主要介绍基于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>

总结

上一篇:微信小程序实现通过js操作wxml的wxss属性示例

栏    目:JavaScript代码

下一篇:如何利用 JS 脚本实现网页全自动秒杀抢购功能

本文标题:基于Typescript与Axios的接口请求管理详解

本文地址:http://www.codeinn.net/misctech/201314.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有