import type { AxiosInstance, AxiosResponse } from 'axios'
import type { McAxiosRequestConfig } from './axios'
import axios from './axios'
type RequestMethod = 'get' | 'post' | 'delete' | 'put'
class Request {
private instance: AxiosInstance
constructor(params: AxiosInstance) {
this.instance = params
}
public get(url: string, config: any = {}): Promise<AxiosResponse<any>> {
return this.request('get', url, config)
}
public post(
url: string,
data: any = {},
config: McAxiosRequestConfig = {},
): Promise<AxiosResponse<any>> {
return this.request('post', url, data, config)
}
public put(
url: string,
data: any = {},
config: McAxiosRequestConfig = {},
): Promise<AxiosResponse<any>> {
return this.request('put', url, data, config)
}
public delete(
url: string,
data: any = {},
config: McAxiosRequestConfig = {},
): Promise<AxiosResponse<any>> {
return this.request('delete', url, data, config)
}
// 新增流式处理方法
public stream(
url: string,
method: RequestMethod = 'get',
config: McAxiosRequestConfig & {
responseType?: 'stream' | 'arraybuffer' | 'blob'
onData?: (chunk: Uint8Array | ArrayBuffer | Blob) => void
onError?: (error: Error) => void
onComplete?: () => void
} = {},
): Promise<AxiosResponse> {
const { onData, onError, onComplete, ...axiosConfig } = config
return new Promise((resolve, reject) => {
this.instance({
method,
url,
...axiosConfig,
onDownloadProgress: (progressEvent) => {
if (progressEvent.event.target instanceof ReadableStream) {
const reader = progressEvent.event.target.getReader()
const readChunk = () => {
reader.read()
.then(({ done, value }: any) => {
if (done) {
onComplete?.()
return
}
onData?.(value)
readChunk()
})
.catch((err: any) => {
onError?.(err)
reject(err)
})
}
readChunk()
}
// 处理ArrayBuffer类型
else if (progressEvent.loaded && progressEvent.total) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)
console.log(`Download progress: ${percent}%`)
}
},
responseType: config.responseType || 'stream',
})
.then((response) => {
// 直接返回原始响应
resolve(response)
})
.catch((error) => {
onError?.(error)
reject(error)
})
})
}
// 修改后的下载方法
public download(
url: string,
params: any = {},
filename?: string,
method: RequestMethod = 'get',
config: McAxiosRequestConfig = {},
): Promise<any> {
return this.stream(url, method, {
...config,
params,
responseType: 'blob',
}).then((res) => {
// 创建下载链接
const url = window.URL.createObjectURL(res.data)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.download = filename || `download_${Date.now()}`
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
})
}
private async request(
method: RequestMethod,
url: string,
config: McAxiosRequestConfig,
...params: any
) {
return await this.instance[method](url, config, ...params)
}
}
export const request = new Request(axios)
这是封装的axios请求文件;// 测试管理 - 测试任务 - 任务详情 - 对比结果 - 查看任务步骤音频文件
async function checkTaskResultAudio(stepId: string) {
const apiUrl = `/test/task/result/download/audio/${stepId}`
return request.stream(apiUrl, 'get', {
responseType: 'arraybuffer',
onData: (chunk) => {
console.log(chunk)
},
})
}这是我请求接口的方式;这是拦截// import { systemApi } from '@/api'
// import { getDefaultLanguage, StorageUtils } from '@/common/utils/StorageUtils'
// import { apiWhiteList, BASE_URL } from '@/config'
import { router } from '@/router/index'
import { clearToken, getToken, useElementPlus } from '@/utils'
// import { useUserStore } from '@/store/user'
import axios, { type AxiosRequestConfig } from 'axios'
const { error, warning } = useElementPlus()
const apiWhiteList = ['/auth/oauth/token']
export class McAxiosRequestConfig implements AxiosRequestConfig<any> {
extraConfig?: {
tokenRetryCount: number
}
headers?: any
baseURL?: string
timeout?: number
method?: string
data?: any
params?: any
responseType?: any
}
const _refreshObj: {
isRefreshing: boolean
requests: Array<Function>
} = {
isRefreshing: false,
requests: [],
}
const BASE_URL = import.meta.env.VITE_BASE_URL
const instance = axios.create({
baseURL: BASE_URL,
timeout: 5 * 60 * 1000,
headers: {
'Content-Type': 'application/json',
},
})
instance.interceptors.request.use(
(config: any) => {
if (config && config?.headers) {
config.headers['X-Requested-With'] = 'XMLHttpRequest'
config.headers['Request-Start'] = new Date().getTime()
}
if (!config.extraConfig?.tokenRetryCount) {
config.extraConfig = {
tokenRetryCount: 0,
}
}
// 判断本地是否有token(保存在cookie中,便于设置过期时间)
const accessToken = getToken() || ''
if (!apiWhiteList.includes(config.url) && accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`
}
if (config.method?.toUpperCase() === 'GET') {
config.params = { ...config.params, _t: new Date().getTime() }
}
if (Object.values(config.headers).includes('application/x-www-form-urlencoded')) {
config.data = JSON.stringify(config.data)
}
return config
},
(err) => {
return Promise.reject(new Error(err))
},
)
instance.interceptors.response.use(
(response) => {
console.log(response, 'response')
if (response.status === 200) {
if (response.data) {
// token过期,强制退出登录
if (response.data.code === 401) {
clearToken()
router.replace('/login')
}
const { code, msg = '' } = response.data
if (code !== 0) {
window.$message.error(msg)
throw new Error(msg)
// return Promise.reject(new Error(msg))
}
return response.data
}
}
return response
},
(err) => {
if (axios.isCancel(err)) {
// 取消的请求,不报错
return
}
if (err.message.includes('timeout')) {
return error('请求超时')
}
warning(err)
return Promise.reject(new Error(err))
},
)
export default instance
最新发布