原代码:
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosRequestHeaders,
AxiosResponse,
AxiosError
} from 'axios'
import qs from 'qs'
import { config} from './config'
import { useCache } from '@/hooks/web/useCache'
import { useAppStore } from "@/store/modules/app";
const { result_code, base_url } = config
export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
const { wsCache } = useCache()
const appStore = useAppStore()
//axios.defaults.baseURL='ssss'
// 创建axios实例
const service: AxiosInstance = axios.create({
baseURL: PATH_URL, // api 的 base_url
timeout: config.request_timeout // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
if (
config.method === 'post' &&
(config.headers as AxiosRequestHeaders)['Content-Type'] ==='application/x-www-form-urlencoded') {
config.data = qs.stringify(config.data)
}
const token=wsCache.get(appStore.getUserInfo)?.Token;
if(token){
(config.headers as AxiosRequestHeaders)['Authorization'] = token
}
// ;(config.headers as AxiosRequestHeaders)['Token'] = 'test test'
// get参数编码
if (config.method === 'get' && config.params) {
let url = config.url as string
url += '?'
const keys = Object.keys(config.params)
for (const key of keys) {
if (config.params[key] !== void 0 && config.params[key] !== null) {
url += `${key}=${encodeURIComponent(config.params[key])}&`
}
}
url = url.substring(0, url.length - 1)
config.params = {}
config.url = url
}
return config
},
(error: AxiosError) => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
(response: AxiosResponse<any>) => {
if (response.config.responseType === 'blob') {
// 如果是文件流,直接过
return response
} else if (response.data.code === result_code) {
return response.data
} else {
//ElMessage.error(response.data.msg)
return response.data
}
},
(error: AxiosError) => {
console.log('err' + error) // for debug
//ElMessage.error(error.message)
return Promise.reject(error)
}
)
export { service }
我想让baseURl的请求地址是从外面调用的,所以改成了下面的:
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosRequestHeaders,
AxiosResponse,
AxiosError
} from 'axios'
import qs from 'qs'
import { config } from './config'
import { ElMessage } from 'element-plus'
const { result_code, base_url } = config
export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
// Call the endpoint to get some necessary data
axios.get('config.json').then((res) => {
console.log(res)
// Create Axios instance with the obtained data
const service: AxiosInstance = axios.create({
baseURL: PATH_URL,
timeout: config.request_timeout
})
// Request interceptor
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
if (
config.method === 'post' &&
(config.headers as AxiosRequestHeaders)['Content-Type'] ===
'application/x-www-form-urlencoded'
) {
config.data = qs.stringify(config.data)
}
if (config.method === 'get' && config.params) {
let url = config.url as string
url += '?'
const keys = Object.keys(config.params)
for (const key of keys) {
if (config.params[key] !== void 0 && config.params[key] !== null) {
url += `${key}=${encodeURIComponent(config.params[key])}&`
}
}
url = url.substring(0, url.length - 1)
config.params = {}
config.url = url
}
return config
},
(error: AxiosError) => {
console.log(error)
Promise.reject(error)
}
)
// Response interceptor
service.interceptors.response.use(
(response: AxiosResponse<any>) => {
if (response.config.responseType === 'blob') {
return response
} else if (response.data.code === result_code) {
return response.data
} else {
ElMessage.error(response.data.message)
}
},
(error: AxiosError) => {
console.log('err' + error)
ElMessage.error(error.message)
return Promise.reject(error)
}
)
export { service }
})
这个这样写的话不能通过,这样写有什么问题吗?
办法总比困难多,根据 ESM 的特性可以这样写:
根据最新的
await
的用法可以修改成下面这样的:这种写法根据 ESM 的特性,导出的是
引用值
,也就是service
如果发生了修改那么在全局使用的范围内都是可以一起改变的,但是需要注意的是,没有初始化成功的时候,service
的值是null
,在使用的时候需要对其进行判,不过也可以将判空也封装进去,使用Promise
来处理:这样写麻烦点在于
getService
每次都要手动获取一次,但是同时也保留了service
,不过service
没有初始化成功的时候是个null
并不稳定,getService
可以保证稳定。基于上面的,其实更建议使用
getService
,因为service
是使用let
来定义的,如果被外部修改了也会有问题,所以可以使用闭包,只保留getService
:最后,如果是使用 CMD 的话,那就只能使用最后的闭包形式了,CMD 是缓存,直接导出的
service
不会发生变化,需要每次通过函数式返回获取最新的service
;