import {
getApptoken,
getStoredApptoken
} from './tokenRequest'
const MAX_RETRIES = 1
const baseURL = 'https://your-api.com'
let requestsQueue = []
let isRefreshing = false
export const request = config => {
return new Promise((resolve, reject) => {
const processedConfig = requestInterceptor({
baseURL,
method: 'POST',
needRefreshToken: true,
retryCount: 0,
...config
})
const separator = processedConfig.url.includes('?') ? '&' : '?'
const url = `${processedConfig.baseURL}${processedConfig.url}${separator}token=${processedConfig.apptoken || ''}`
uni.request({
...processedConfig,
url,
success: response => {
responseInterceptor(response, processedConfig)
.then(resolvedData => resolve(resolvedData))
.catch(err => reject(err))
},
fail: error => {
console.error(`请求失败:${processedConfig.url}`, error)
reject(error)
}
})
})
}
const requestInterceptor = config => {
config.header = {
'Content-Type': 'application/json',
...config.header
}
if (config.needRefreshToken) {
const token = getStoredApptoken()
if (token) {
config.token = token
}
}
return config
}
const responseInterceptor = async (response, config) => {
const {
data,
statusCode
} = response
if (statusCode === 200) {
return data
}
if ((statusCode === 401 || statusCode === 400) && config.needRefreshToken) {
if (config.retryCount >= MAX_RETRIES) {
uni.showToast({
title: '重试次数过多,请稍后再试',
icon: 'none'
})
return Promise.reject(new Error('重试次数过多'))
}
if (isRefreshing) {
return new Promise(resolve => {
requestsQueue.push(() => resolve(request({
...config,
retryCount: config.retryCount + 1
})))
})
}
isRefreshing = true
try {
const refreshSuccess = await getApptoken()
if (!refreshSuccess) {
return Promise.reject(new Error('获取新的token失败'))
}
const retryResponse = await request({
...config,
retryCount: config.retryCount + 1
})
requestsQueue.forEach(callback => callback())
requestsQueue = []
return retryResponse
} catch (refreshError) {
console.error('刷新token出错', refreshError)
uni.showToast({
title: '认证失败,请重新登录',
icon: 'none'
})
return Promise.reject(refreshError)
} finally {
isRefreshing = false
}
}
return Promise.reject(new Error(`请求失败,状态码:${statusCode}`))
}
export const requestPost = (url, data, config = {}) => {
return request({
url,
data,
method: 'POST',
...config
})
}
export const requestGet = (url, config = {}) => {
return request({
url,
method: 'GET',
...config
})
}
const infoObj = {
appkey: process.env.ENV_TYPE === 'prod' ? 'C1A1140xxxxxxxxxxxxxxxxxxxxxxxxxxxx' :
'3232313xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
appSecret: process.env.ENV_TYPE === 'prod' ? '34D7C4Exxxxxxxxxxxxxxxxxxxxxxxxxxxx' :
'0A779D4xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
token: ''
}
const baseURL = 'https://your-api.com'
const baseRequest = config => {
return new Promise((resolve, reject) => {
uni.request({
method: 'GET',
header: { 'Content-Type': 'application/json' },
dataType: 'json',
...config,
success: response => resolve(response.data),
fail: error => reject(error)
})
})
}
export const getApptoken = () => {
return new Promise((resolve, reject) => {
const oldtoken = getStoredApptoken()
const tokenUrl = `${baseURL}/getToken?token=${oldtoken}`
baseRequest({ url: tokenUrl })
.then(res => {
if (res.token) {
infoObj.token = res.token
uni.setStorageSync('infoObj', JSON.stringify(infoObj))
resolve(true)
} else {
uni.showToast({
title: '更新token出错',
icon: 'none'
})
resolve(false)
}
})
.catch(err => {
console.error('获取token接口失败', err)
uni.showToast({
title: '更新token接口出错',
icon: 'none'
})
resolve(false)
})
})
}
export const getStoredApptoken = () => {
try {
const stored = uni.getStorageSync('infoObj')
return stored ? JSON.parse(stored).token : ''
} catch (error) {
console.error('获取存储的token失败', error)
return ''
}
}
const submitData = async () => {
try {
const params = { name: 'test', age: 20 };
const res = await requestPost('/api/submit', params);
console.log('提交成功', res);
} catch (err) {
console.error('提交失败', err);
}
};