修复web端请求bug

This commit is contained in:
范鹏 2024-12-23 15:08:51 +08:00
parent 8f690534cf
commit a3032a9c6e

View File

@ -1,104 +1,155 @@
import { getStorage, removeStorage } from '../export.js'
import { buildNumber, getStorage, removeStorage, version } from '../export'
import starCloudInstance from '../star-cloud'
import { Result } from '../constant'
/*
* config
* baseUrl: 请求域名
* url: 请求路径
* method: 请求方法
* header: 请求头
* token: 请求token
* data: 请求参数
* */
const request = config => {
let timer
let res = null // 在外部定义res避免finally块报错
const request = (config) => {
return new Promise(async resolve => {
const baseConfig = starCloudInstance.getConfig()
const token = config?.token ? config.token : getStorage('starCloudToken')
// 请求地址
const URL = config.baseUrl ? config.baseUrl + config.url : baseConfig.baseUrl + config.url
// 默认请求头
const headerDefault = {
version: baseConfig.version + '+' + baseConfig.buildNumber
}
const header = {
...headerDefault,
...config.header
}
const method = config.method || 'POST'
const data = {
...config.data,
accessToken: token,
clientId: starCloudInstance.clientId
}
const timestamp = new Date().getTime()
// 超时处理
timer = setTimeout(() => {
resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常'))
}, 3200)
try {
const response = await fetch(URL, {
method,
headers: {
...header,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
const starCloud = starCloudInstance
const baseConfig = starCloud.getConfig()
const token = config?.token || getStorage('starCloudToken')
const timestamp = new Date().getTime()
res = await response.json() // 在这里将res赋值
if (timer) {
clearTimeout(timer)
// 获取正确的版本号和构建号
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
}
if (response.ok) {
const { errcode, errmsg, data } = res
if (errcode === 10003) {
removeStorage('starCloudToken')
removeStorage('starCloudUser')
const { code } = await starCloudInstance.login({
username: starCloudInstance.starCloudAccountInfo.username,
password: starCloudInstance.starCloudAccountInfo.password,
uid: starCloudInstance.starCloudAccountInfo.uid
})
if (code === Result.Success.code) {
resolve(await request(config))
// 处理 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({
username: starCloud.starCloudAccountInfo.username,
password: starCloud.starCloudAccountInfo.password,
uid: starCloud.starCloudAccountInfo.uid
})
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({
code: errcode,
data,
message: errmsg
})
resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常'))
}
} else {
}
// 处理错误
xhr.onerror = function() {
if (timer) {
clearTimeout(timer)
}
console.log('网络访问失败', xhr.status, xhr.statusText)
resolve(new Result(Result.Fail.code, {}, '网络访问失败,请检查网络是否正常'))
}
} catch (error) {
console.log('网络访问失败', error)
if (timer) {
clearTimeout(timer)
// 处理超时
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, {}, '网络访问失败,请检查网络是否正常'))
} finally {
// 访问res时确保它已定义
console.log(URL.substring(baseConfig.baseUrl.length + 1), {
env: baseConfig.name,
url: URL.substring(baseConfig.baseUrl.length + 1),
req: config?.data || {},
code: res?.errcode || null, // 如果res未定义fallback为null
res: res?.data || null, // 如果res未定义fallback为null
token: header?.authorization || '',
message: res?.errmsg || '', // 如果res未定义fallback为空字符串
duration: new Date().getTime() - timestamp
})
}
})
}