import { buildNumber, getStorage, removeStorage, version } from '../export' import starCloudInstance from '../star-cloud' import { Result } from '../constant' const request = (config) => { return new Promise(async resolve => { try { const starCloud = starCloudInstance const baseConfig = starCloud.getConfig() const token = config?.token || getStorage('starCloudToken') const timestamp = new Date().getTime() // 获取正确的版本号和构建号 let currentVersion = typeof version === 'function' ? version() : version let currentBuildNumber = typeof buildNumber === 'function' ? buildNumber() : buildNumber // 构建请求 URL const baseUrl = config.baseUrl || baseConfig.baseUrl let url = baseUrl + config.url // 构建请求数据 const requestData = { ...config.data, accessToken: token, clientId: starCloud.clientId } // 处理 GET 请求的参数 const method = (config.method || 'POST').toUpperCase() if (method === 'GET') { const params = new URLSearchParams() Object.entries(requestData).forEach(([key, value]) => { if (value != null) { params.append(key, String(value)) } }) const queryString = params.toString() if (queryString) { url += (url.includes('?') ? '&' : '?') + queryString } } // 创建 XHR 对象 const xhr = new XMLHttpRequest() let timer = null // 设置超时 xhr.timeout = 3200 // 打开连接 xhr.open(method, url, true) // 设置请求头 xhr.setRequestHeader('Content-Type', 'application/json') xhr.setRequestHeader('version', `${currentVersion}+${currentBuildNumber}`) if (config.header) { Object.entries(config.header).forEach(([key, value]) => { if (value != null) { xhr.setRequestHeader(key, String(value)) } }) } // 关闭 withCredentials,使用其他方式传递凭证 xhr.withCredentials = false // 处理响应 xhr.onload = async function() { if (timer) { clearTimeout(timer) } if (xhr.status === 200) { try { const responseData = JSON.parse(xhr.responseText) const code = responseData.errcode const message = responseData.errmsg // 处理 token 过期 if (code === 10003) { removeStorage('starCloudToken') removeStorage('starCloudUser') const loginResult = await starCloud.login(starCloud.accountInfo.uid, true) if (loginResult.code === Result.Success.code) { return resolve(await request(config)) } } // 记录日志 console.log('请求完成', { env: baseConfig.name, url: url.replace(baseUrl, ''), req: config?.data || {}, code: responseData.errcode, res: responseData.data, token: config.header?.authorization || '', message: responseData.errmsg, duration: new Date().getTime() - timestamp }) resolve({ code, data: responseData.data, message }) } catch (error) { console.log('解析响应失败', error) resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) } } else { resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) } } // 处理错误 xhr.onerror = function() { if (timer) { clearTimeout(timer) } console.log('网络访问失败', xhr.status, xhr.statusText) resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) } // 处理超时 xhr.ontimeout = function() { if (timer) { clearTimeout(timer) } console.log('请求超时') resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) } // 发送请求 if (method === 'GET') { xhr.send() } else { xhr.send(JSON.stringify(requestData)) } // 额外的超时保护 timer = setTimeout(() => { xhr.abort() resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) }, 3200) } catch (error) { console.log('请求错误', error) resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常')) } }) } export default request