1. 代码
import Notice from '@util/notice' // 是自己写的一个toast类
import { noticeTypes } from '@util/notice/type'
type controlType = {
upload?: 'false' | 'true'
file?: 'false' | 'true'
cache?: 'false' | 'true'
}
export class Request {
baseURL = import.meta.env.VITE_BASE_URL
static instance: Request | null = null
static getInstance() {
return Request.instance || new Request()
}
// 前置拦截
beforeFetch(url: string, props: any) {
let baseHeader: Object = {
Authorization: 'Bearer ' + localStorage.getItem('token') || sessionStorage.getItem('token') || '',
Accept: 'application/json'
}
if (url.startsWith(this.baseURL)) {
baseHeader = {
...baseHeader,
// 在baseURL路径下添加请求权限(添加一些特殊的请求头)
}
}
// 上传时候 fetch 自动设置 'Content-Type'
if (!props.headers?.upload || props.headers?.upload === 'false') {
baseHeader = {
...baseHeader,
'Content-Type': 'application/json;charset=UTF-8'
}
}
// fetch 缓存
if (props.headers?.cache === 'false') {
baseHeader = {
...baseHeader,
'Cache-Control': 'no-store'
}
}
props.headers = { ...baseHeader, ...props.headers }
}
// 后置拦截
afterFetch(response: any, props: RequestInit & { headers?: controlType }) {
if (props.headers?.file === 'true') {
// 文件直接通行
return response
} else if (response.status !== 200) {
return new Notice().error(response.message)
} else {
// 后台返回的数据控制是否 toast 显示
if (response.showMessage) {
const type = (response.messageType as noticeTypes) || 'success'
new Notice()[type](response.message)
}
return response
}
}
// 请求
async request(url: string, props: RequestInit & { headers?: controlType }) {
const newURL = this.joinUrl(url)
this.beforeFetch(newURL, props)
try {
let response: any
if (props.headers?.file === 'true') {
response = await (await fetch(newURL, props)).blob()
} else {
response = await (await fetch(newURL, props)).json()
}
return this.afterFetch(response, props)
} catch (e: any) {
return {
status: 1000,
message: e.message
}
}
}
// 拼接URL
joinUrl(url: string) {
if (url.startsWith('http')) {
return url
}
return this.baseURL + url
}
}
2. 使用
api.ts
import { Request } from '@http/fetch'
// 获取足迹列表
export const getFootmarkListAPI = async (props: RequestInit = {}) => {
const response = await Request.getInstance().request('/global/getFootmarkList', { ...props, method: 'POST' })
return response
}
xxx.vue
// 获取足迹目录
const getFootmarkList = async () => {
const response = await getFootmarkListAPI({
body: JSON.stringify({
type: 1,
pageNumber: 1,
pageSize: 10,
permission: 100
})
})
if (response.status === 200) {
console.log(response.data)
}
}