
Axios二次封装最佳实践
一般自己写 SPA,Axios 基本是首选的 HTTP Library,而对于它的二次封装所谓的“最佳实践”又层出不穷,在这里给一下我的方案吧(其实也是为了方便我自己随时随地 copy)
52字
目标
简单,开箱即用,不用配乱七八糟的文件,最好一个文件完事
TS 项目
type 应该最好还是单独放一个文件吧...?
src/service/index.ts
typescript
import type { AxiosError, AxiosInstance } from 'axios'
import type { CustomRequestConfig, IApiResponse } from './types'
import axios from 'axios'
function request<TRequest = any, TResponse = any>(
config: CustomRequestConfig<TRequest>,
): Promise<TResponse> {
const instance: AxiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
})
instance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error: AxiosError) => {
return Promise.reject(error)
},
)
instance.interceptors.response.use(
(response) => {
const res = response.data as IApiResponse<TResponse>
if (res.code !== 0 && res.code !== 200) {
if (res.code === 401) {
console.error('Login expired, please log in again!')
}
if (config.showError !== false) {
console.error(res.message || 'Error')
}
return Promise.reject(new Error(res.message || 'Error'))
}
response.data = res.data
return response
},
(error: AxiosError) => {
let message = ''
if (error.response) {
switch (error.response.status) {
case 400:
message = 'Bad Request (400)'
break
case 401:
message = 'Unauthorized, please log in again (401)'
break
case 403:
message = 'Forbidden (403)'
break
case 404:
message = 'Not Found (404)'
break
case 500:
message = 'Internal Server Error (500)'
break
default:
message = `Connection error (${error.response.status})!`
}
}
else if (error.request) {
message = 'Network connection timeout!'
}
else {
message = 'Request failed, please check your network!'
}
if (config.showError !== false) {
console.error(message)
}
return Promise.reject(error)
},
)
return instance.request<any, TResponse>(config)
}
export default request
src/service/types.ts
typescript
import type { AxiosRequestConfig } from 'axios'
export interface CustomRequestConfig<TRequest = any> extends AxiosRequestConfig {
showLoading?: boolean
showError?: boolean
data?: TRequest
}
export interface IApiResponse<T = any> {
code: number
message: string
data: T
}
JS 项目
类型提示用 JSDoc!黑科技
src/service/index.js
javascript
import axios from 'axios'
/**
* @typedef {import('axios').AxiosRequestConfig & {showError?: boolean, showLoading?: boolean}} CustomRequestConfig
*/
/**
* General request function based on Axios
* @param {CustomRequestConfig} config Custom request configuration
* @returns {Promise<any>} A Promise that resolves with the backend's data field on success, or throws an error on failure
*/
function request(config) {
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
})
instance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
},
)
instance.interceptors.response.use(
(response) => {
const res = response.data
if (res.code !== 0 && res.code !== 200) {
if (res.code === 401) {
console.error('Login expired, please log in again!')
}
if (config.showError !== false) {
console.error(res.message || 'Error')
}
return Promise.reject(new Error(res.message || 'Error'))
}
return res.data
},
(error) => {
let message = ''
if (error.response) {
switch (error.response.status) {
case 400:
message = 'Bad Request (400)'
break
case 401:
message = 'Unauthorized, please log in again (401)'
break
case 403:
message = 'Forbidden (403)'
break
case 404:
message = 'Not Found (404)'
break
case 500:
message = 'Internal Server Error (500)'
break
default:
message = `Connection error (${error.response.status})!`
}
}
else if (error.request) {
message = 'Network connection timeout!'
}
else {
message = 'Request failed, please check your network!'
}
if (config.showError !== false) {
console.error(message)
}
return Promise.reject(error)
},
)
return instance.request(config)
}
export default request
评论0