1、前期准备
下载相关依赖
yarn add axios
or
npm install axios
yarn add antd(主要用于提示,可自行选择)
or
npm install antd(主要用于提示,可自行选择)
2、目录结构
/request/index.ts
/request/interceptors.ts
3、才艺表演
3.1 interceptors.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { message } from 'antd'
// 请求拦截器
export const requestInterceptor = (instance: AxiosInstance) => {
instance.interceptors.request.use(
function (config) {
CancelToken.addRequest(config)
return config
},
function (error) {
return Promise.reject(error)
}
)
}
type ResponseType<T = any> = {
code?: string
msg?: string
data?: T
}
// 响应拦截器
export const responseInterceptor = (instance: AxiosInstance) => {
instance.interceptors.response.use(
function (response: AxiosResponse<ResponseType>) {
const key: string = CancelToken.getKey(response.config)
CancelToken.cencelRequest(key)
if (response?.data?.code === '200') {
return Promise.resolve(response.data)
}
businessStatus(response)
return Promise.reject(response.data)
},
function (error) {
if (error?.code === 'ERR_NETWORK') {
message.error('网络错误,请检查网络')
}
if (error?.code === 'ECONNABORTED') {
message.error('请求超时')
}
if (error?.code === 'ERR_CANCELED') {
console.warn(`${error.message}请求已取消`)
}
if (error.response?.status) {
browserStatus(error.response, error.config)
}
return Promise.reject(error)
}
)
}
// 业务状态处理
const businessStatus = (response: any) => {
if (response.data.code === 'xxx') {
// 指定code业务处理
message.error(response.data.msg)
} else {
response.data.msg && message.error(response.data.msg)
}
}
// 浏览器状态处理
const browserStatus = (response: any, config: any) => {
switch (response.status) {
// 未登录
case 401:
message.error('用户未登录')
// 可自行处理跳登录页面
break
// 登录过期
case 403:
message.error('登录状态已过期')
// 可自行处理跳登录页面
break
//资源不存在
case 404:
message.error(`${config.url} 资源不存在`)
// 可自行处理跳404页面
break
// 服务端错误
case 500:
message.error('服务端错误')
break
// 其他status
default:
message.error('网络错误,请刷新后再试')
break
}
}
// 取消请求
export class CancelToken {
// 存储每个请求的标识
static requestList = new Map()
// 白名单(不进行取消请求) 请求方式-接口(例如:get-/menus)
static whiteList: Array<string> = []
// 获取key
static getKey(config: AxiosRequestConfig): string {
return `${config.method}-${config.url}`
}
// 验证接口是否被加入白名单
static verifyWhiteList(config: AxiosRequestConfig): boolean {
const key: string = this.getKey(config)
return this.whiteList.includes(key)
}
// 添加请求
static addRequest(config: AxiosRequestConfig) {
const key: string = this.getKey(config)
config.cancelToken = new axios.CancelToken((cancel) => {
// 若请求已存在(请求中)则取消上一次的请求
if (this.requestList.has(key)) {
// cancel(key) // 取消当前请求
this.cencelRequest(key) // 取消上一次请求
} else if (!this.requestList.has(key) && !this.verifyWhiteList(config)) {
// 请求不存在并且不在白名单
this.requestList.set(key, cancel)
}
})
}
// 取消单个请求
static cencelRequest(key: string) {
if (this.requestList.has(key)) {
// 取消请求
this.requestList.get(key)(key)
// 删除当前请求
this.requestList.delete(key)
}
}
// 取消全部请求
static cencelAllRequest() {
// 遍历请求列表 全部取消
for (const [url, cancel] of this.requestList) {
cancel(url)
}
this.requestList.clear()
}
}
3.2 index.ts(可创建多个axios实例)
import axios from 'axios'
import { requestInterceptor, responseInterceptor } from './interceptors'
const baseURL = 'http://xxxxxx1'
const baseURL2 = 'http://xxxxxx2'
// 初始化1
const instance = axios.create({
baseURL: baseURL,
timeout: 1000 * 20,
withCredentials: true,
})
// 初始化2
const instance2 = axios.create({
baseURL: baseURL2,
timeout: 1000 * 20,
withCredentials: true,
})
// 请求拦截器1
requestInterceptor(instance)
// 请求拦截器2
requestInterceptor(instance2)
// 响应拦截器1
responseInterceptor(instance)
// 响应拦截器2
responseInterceptor(instance2)
export default instance
4、如何使用
import axios from '@/request/index'
export enum Api {
getList = '/api/getList',
addForm = '/api/addForm',
updateForm = '/api/updateForm',
deleteUser = '/api/deleteUser',
}
// GET
export const getList = (params: any) => {
return axios.get(Api.getList, { params })
}
// POST
export const addForm = (params: any) => {
return axios.post(Api.addForm, params)
}
// PUT
export const updateForm = (params: any) => {
return axios.put(Api.updateForm, params)
}
// DELETE
export const deleteUser = (params: any) => {
return axios.delete(Api.deleteUser, { params })
}