企业网站ui,wordpress首页div,网站模版 之星,百度竞价渠道代理目录 前后端交互约定安装创建Axios实例拦截器封装请求方法业务异常处理 axios 是一个易用、简洁且高效的http库 axios 中文文档#xff1a;http://www.axios-js.com/zh-cn/docs/ 前后端交互约定
在本项目中#xff0c;前后端交互统一使用 application/json;charsetUTF-8 的请… 目录 前后端交互约定安装创建Axios实例拦截器封装请求方法业务异常处理 axios 是一个易用、简洁且高效的http库 axios 中文文档http://www.axios-js.com/zh-cn/docs/ 前后端交互约定
在本项目中前后端交互统一使用 application/json;charsetUTF-8 的请求方式后端返回对象统一为如下格式
export interface ResponseBodyT any {status: boolean, // 业务处理状态true表示正常false表示异常code: string // 业务处理状态码message: string, // 提示信息data?: T // 业务处理返回数据
}安装
yarn add axios创建Axios实例 在 src 目录下创建 http 目录http 请求相关的文件都放置于该目录 创建 axios.ts 文件用于定义 axios
// axios.ts
const instance: AxiosInstance axios.create({baseURL: import.meta.env.VITE_APP_BASE_API,timeout: 60000,headers: { Content-Type: application/json;charsetUTF-8 },
})其中import.meta.env.VITE_APP_BASE_API 是 .env 中配置的环境变量不同环境使用不同的请求地址
拦截器
通过 instance.interceptors.request.use 实现前置拦截器发起请求前执行用于对请求对象进行加工处理。
下面这段代码主要做的事情就是将 token 设置到请求头中。
// axios.ts
async function requestHandler(config: InternalAxiosRequestConfig RequestConfigExtra): PromiseInternalAxiosRequestConfig {if (config.modulePrefix) {config.url config.modulePrefix config.url}const token useAuthorization()if (token.value config.token ! false) {config.headers.set(Authorization, token.value)}console.log(execute http request config.url)return config
}instance.interceptors.request.use(requestHandler)RequestConfigExtra 为自定义参数在本项目中定义如下可根据需要自行扩展。
export interface RequestConfigExtra {// 模块前缀modulePrefix?: string,// 发起请求时是否需要在请求头中附加 tokentoken?: boolean,// 成功处理函数默认为 false如果为 false则什么都不做如果为 true则自动提示成功信息如果为 Function则自定义处理结果success?: boolean | ((response: ResponseBodyany) void),// 失败处理函数默认为 true如果为 false则什么都不做如果为 true则自动提示失败信息如果为 Function则自定义处理结果error?: boolean | ((response: ResponseBodyany) void),
}通过 instance.interceptors.response.use 实现后置拦截器对后端返回数据进行处理。
function responseHandler(response: any): ResponseBodyany | AxiosResponseany | Promiseany | any {return response.data
}function errorHandler(errorInfo: AxiosError): Promiseany {if (errorInfo.response) {const { data, status, statusText } errorInfo.response as AxiosResponseResponseBodyif (status 401) {const token useAuthorization()token.value nullmessage.error(data?.message || statusText)router.push({path: /login, query: { redirect: router.currentRoute.value.fullPath}})} else {message.error(data?.message || statusText)} }return Promise.reject(errorInfo)
}instance.interceptors.response.use(responseHandler, errorHandler)errorHandler 方法对系统异常进行了统一处理如果后端返回的 status 不是 200则会执行该处理方法如果返回 401表示没有通过登录鉴权自动跳转登录页如果是其它异常码则提示错误信息。
封装请求方法
这里对 restful 常用的四种请求方式进行进一步的封装
// axios.ts
function instancePromiseR any, T any(options: AxiosRequestConfigT RequestConfigExtra): PromiseResponseBodyR {return new Promise((resolve, reject) {instance.requestany, ResponseBodyR(options).then((res) {try {resolve(responseBodyHandle(res, options))} catch (err) {reject(err || new Error(response handle error!))}}).catch((e: Error | AxiosError) {reject(e)})})
}export function doGetR any, T any(url: string, params?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,params,method: RequestEnum.GET,...config,}return instancePromiseR, T(options)
}export function doPostR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.POST,...config,}return instancePromiseR, T(options)
}export function doPutR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.PUT,...config,}return instancePromiseR, T(options)
}export function doDeleteR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.DELETE,...config,}return instancePromiseR, T(options)
}业务异常处理
在拦截器中我们对系统异常进行了统一处理在实际项目中更多的情况是前端请求没有通过后端的业务校验后端返回错误信息前端进行提示。
创建一个业务异常类
export class ResponseBodyError extends Error {code: stringmessage: stringcause: anyconstructor({ code, message, cause }: { code: string, message: string, cause?: any }) {super();this.code code;this.message message;this.cause cause}
}实现业务异常统一处理通过在请求时定义 RequestConfigExtra 中的参数来实现对后端返回结果的提示。
比如查询请求设置为 {success:false, error: true}如果请求失败提示错误信息如果请求成功不作处理。业务请求设置为 {success: true, error: true}如果请求失败提示错误信息如果处理成功提示操作成功。
function responseBodyHandleR any, T any(response: ResponseBodyR, options: AxiosRequestConfigT RequestConfigExtra): any {const { status, message:msg, code, data } responseconst { success, error } optionsif (status true) {if (success true) {message.success(msg ?? 操作成功)} else if (isFunction(success)) {success(response)}return response} else {if (isFunction(error)) {error(response)} else if (error ! false) {message.error(msg ?? 操作失败)}throw new ResponseBodyError({ code, msg })}
}完整代码如下
// axios.ts
/*** 创建 Axios 实例*/
const instance: AxiosInstance axios.create({baseURL: import.meta.env.VITE_APP_BASE_API,timeout: 60000,headers: { Content-Type: application/json;charsetUTF-8 },
})/*** 前置拦截器*/
async function requestHandler(config: InternalAxiosRequestConfig RequestConfigExtra): PromiseInternalAxiosRequestConfig {if (config.modulePrefix) {config.url config.modulePrefix config.url}const token useAuthorization()if (token.value config.token ! false) {config.headers.set(authorizationHeader, authorizationValue())}console.log(execute http request config.url)return config
}/*** 后置拦截器*/
function responseHandler(response: any): ResponseBodyany | AxiosResponseany | Promiseany | any {return response.data
}/*** 系统异常统一处理函数*/
function errorHandler(errorInfo: AxiosError): Promiseany {if (errorInfo.response) {const { data, status, statusText } errorInfo.response as AxiosResponseResponseBodyif (status 401) {const token useAuthorization()token.value nullmessage.error(data?.message || statusText)router.push({path: /login, query: { redirect: router.currentRoute.value.fullPath}})} else {message.error(data?.message || statusText)} }return Promise.reject(errorInfo)
}instance.interceptors.request.use(requestHandler)
instance.interceptors.response.use(responseHandler, errorHandler)/*** 业务异常统一处理函数*/
function responseBodyHandleR any, T any(response: ResponseBodyR, options: AxiosRequestConfigT RequestConfigExtra): any {const { status, message:msg, code, data } responseconst { success, error } optionsif (status true) {if (success true) {message.success(msg ?? 操作成功)} else if (isFunction(success)) {success(response)}return response} else {if (isFunction(error)) {error(response)} else if (error ! false) {message.error(msg ?? 操作失败)}throw new ResponseBodyError({ code, msg })}
}function instancePromiseR any, T any(options: AxiosRequestConfigT RequestConfigExtra): PromiseResponseBodyR {return new Promise((resolve, reject) {instance.requestany, ResponseBodyR(options).then((res) {try {resolve(responseBodyHandle(res, options))} catch (err) {reject(err || new Error(response handle error!))}}).catch((e: Error | AxiosError) {reject(e)})})
}export function doGetR any, T any(url: string, params?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,params,method: RequestEnum.GET,...config,}return instancePromiseR, T(options)
}export function doPostR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.POST,...config,}return instancePromiseR, T(options)
}export function doPutR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.PUT,...config,}return instancePromiseR, T(options)
}export function doDeleteR any, T any(url: string, data?: T, config?: AxiosRequestConfig RequestConfigExtra): PromiseResponseBodyR {const options {url,data,method: RequestEnum.DELETE,...config,}return instancePromiseR, T(options)
}