vue3+ts+vite axios的封装,axios 声明合并扩展AxiosRequestConfig额外参数 第五回
// 安装axios npm install axios 和第三方js-cookie、qs 。懂的都懂。
由于很多业务复杂,后端被拆分成多个微服务,所以axios必须来一层简单的封装。下面贴出整个request.ts 脚本
在types目录下,新建axios.d.ts ,内容如下
import { AxiosRequestConfig } from 'axios'
declare module 'axios' {
export interface AxiosRequestConfig {
/** 服务名 */
serv?: string
/** api版本 */
apiVersion?: string
/** 是否需要loading */
needLoading?: boolean
}
}
import { ElLoading } from 'element-plus'
import axios from 'axios'
import qs from 'qs'
import Cookies from 'js-cookie'
// 定义一个常见后端请求返回
type BaseApiResponse = {
code: number
message: string
data: any
status: boolean
}
const request = axios.create({
baseURL: 'http://xxx',
timeout: 300000, // 请求超时时间
paramsSerializer: params => {
return qs.stringify(params, { indices: false })
}
})
// 这里需要注意,按需引入的时候,需要在main.ts引入样式 import 'vue-simple-uploader/dist/style.css'
const defaultElLoadingOptions = {
lock: true,
text: '请稍后',
body: true,
background: 'rgba(0, 0, 0, 0.1)'
}
let loadingInstance: any = null
/**
* interceptor request
* AxiosRequestConfig额外扩展的serv(微服务名),apiVersion
*/
request.interceptors.request.use((config) => {
if (config.serv) {
config.baseURL += `${config.serv}/${config.apiVersion}`
}
const token = Cookies.get('login_ticket')
config.headers['Authorization'] = decodeURIComponent(token);
if (config.method === 'get' || config.method === 'GET') {
config.params = config.data
}
if (config.needLoading) {
loadingInstance = ElLoading.service(defaultElLoadingOptions)
setTimeout(() => {
loadingInstance.close()
}, 30000)
}
return config
},
error => {
Promise.reject(error)
loadingInstance.close()
}
)
// 不需要登录的白名单
const needLogin = (hash: string) => {
let path = /login|register\/public/
const witePaths = [
'#/',
'#/public'
'#/login'
];
return (
witePaths.indexOf(hash.split('?')[0]) === -1
&& hash.search(path) === -1
);
}
// interceptor response
request.interceptors.response.use(
async response => {
if (response.headers && response.headers.authorization) {
Cookies.set('token', response.headers.authorization)
}
const dataAxios = response.data
if (loadingInstance) {
loadingInstance.close()
}
if (dataAxios && dataAxios.httpCode - 0 === 401 && needLogin(location.hash)) {
localStorage.setItem('source', encodeURIComponent(location.href))
location.href = `/#/login`
return
}
// 这个状态码是和后端约定的
// const { status } = response
let status = null
if (dataAxios.status && !isNaN(dataAxios.status - 0)) {
status = dataAxios.status
}
if (dataAxios.code && !isNaN(dataAxios.code - 0)) {
status = dataAxios.code
}
// 根据 code 进行判断
if (status !== null) {
// 有 code 代表这是一个后端接口 可以进行进一步的判断
switch (status) {
case 0:
return dataAxios.result || dataAxios.result == 0 ? dataAxios.result : dataAxios
case 200:
return dataAxios.result || dataAxios.result == 0 ? dataAxios.result : dataAxios
case 401:
if (needLogin(location.hash)) {
// 处理token置换,或者登陆跳转,
}
return
case 'xxx':
// [ 示例 ] 其它和后台约定的 code
break
default:
// 不是正确的 code
// errorCreate(`${dataAxios.message}`)
break
}
} else {
// 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本
return dataAxios
}
},
error => {
if (loadingInstance) {
loadingInstance.close()
}
if (error && error.response) {
if (error.response.data && error.response.data.message && error.response.data.message == '无访问权限') {
location.href = '/home'
return
}
switch (error.response.status) {
case 400: error.message = `请求错误: ${error.response.data && error.response.data.message}`; break
case 401: error.message = '未授权,请登录';
Cookies.set('login_ticket', '');
Cookies.set('refresh_token', '');
location.href = `/#/login?source=${encodeURIComponent(location.href)}`; break
case 403: error.message = '拒绝访问'; break
case 404: error.message = `请求地址出错: ${error.response.config.url}`; break
case 408: error.message = '请求超时'; break
case 500: error.message = '服务器内部错误'; break
case 501: error.message = '服务未实现'; break
case 502: error.message = '网关错误'; break
case 503: error.message = '服务不可用'; break
case 504: error.message = '网关超时'; break
case 505: error.message = 'HTTP版本不受支持'; break
default: break
}
}
// errorLog(error)
return Promise.reject(error)
}
)
export default request
至此,axios的封装告一段落。调用的部分如下。
import request from '@/utils/request'
// // 验证码
export function getVerificationCode() {
return request({
method: 'get',
url: '/verification/code',
serv: '/auth',
apiVersion: 'v1',
needLoading: true
}
)
}
本文来自博客园,作者:大楚打码人,转载请注明原文链接:https://www.cnblogs.com/qh1688/p/17457625.html
浙公网安备 33010602011771号