2025.3.3
这段代码是前端实现文件上传的核心模块,主要包含请求配置、身份验证、错误处理等功能。以下是详细解析:
代码结构解析
1. 模块导入
import store from '@/store' // 状态管理(Vuex)
import config from '@/config' // 项目配置
import { getToken } from '@/utils/auth' // 认证相关工具
import errorCode from '@/utils/errorCode' // 错误码映射
import { toast, showConfirm, tansParams } from '@/utils/common' // 通用工具
- 核心依赖:集成了状态管理、项目配置和工具函数
2. 基础配置
let timeout = 10000 // 默认超时时间
const baseUrl = config.baseUrl // 从配置获取基础API地址
- 超时控制:10秒无响应自动终止请求
- 环境适配:通过
config.baseUrl
实现多环境切换
核心函数 upload
1. 身份验证处理
// 是否需要携带Token (默认携带)
const isToken = (config.headers || {}).isToken === false
config.header = config.header || {}
if (getToken() && !isToken) {
config.header['Authorization'] = 'Bearer ' + getToken()
}
- 鉴权逻辑:
- 默认携带Token
- 可通过
headers: { isToken: false }
禁用
- Token格式:Bearer Token标准方案
2. GET参数处理
if (config.params) {
let url = config.url + '?' + tansParams(config.params)
url = url.slice(0, -1) // 去除末尾多余的&
config.url = url
}
- URL参数序列化:使用
tansParams
转换对象为查询字符串 - 适用场景:需要GET参数的文件下载接口
3. 上传请求封装
return new Promise((resolve, reject) => {
uni.uploadFile({
timeout: config.timeout || timeout, // 超时配置
url: baseUrl + config.url, // 完整请求地址
filePath: config.filePath, // 待上传文件路径
name: config.name || 'file', // 上传字段名(默认file)
header: config.header, // 自定义请求头
formData: config.formData, // 附加表单数据
// 成功回调
success: (res) => {
// 响应处理逻辑...
},
// 失败回调
fail: (error) => {
// 错误处理逻辑...
}
})
})
响应处理逻辑
成功回调处理流程
let result = JSON.parse(res.data) // 解析响应数据
const code = result.code || 200 // 获取状态码
const msg = errorCode[code] || result.msg || errorCode['default'] // 获取错误信息
// 状态码分支处理
if (code === 200) {
resolve(result) // 成功处理
} else if (code == 401) { // 未授权
showConfirm("登录过期提示").then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(() => { // 执行登出
uni.reLaunch({ url: '/login' }) // 跳转登录页
})
}
})
reject('会话过期提示')
} else if (code === 500) { // 服务器错误
toast(msg)
reject('500')
} else if (code !== 200) { // 其他错误
toast(msg)
reject(code)
}
失败回调处理
let { message } = error
// 错误类型判断
if (message == 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(-3) + '异常'
}
toast(message) // 显示错误提示
reject(error) // 传递错误对象
代码亮点分析
-
安全设计
- 自动携带Token机制
- 401自动登出保护
-
健壮性设计
- 多层错误码映射 (
errorCode
) - 网络异常分类处理
- 多层错误码映射 (
-
用户体验优化
- 统一错误提示 (
toast
) - 会话过期二次确认弹窗
- 统一错误提示 (
-
可维护性
- 配置参数分离 (
config.js
) - 状态码集中管理
- 配置参数分离 (
潜在改进建议
- 文件校验增强
// 上传前校验文件类型和大小
const MAX_SIZE = 10 * 1024 * 1024 // 10MB
if (config.file.size > MAX_SIZE) {
return reject('文件大小超过限制')
}
- 进度反馈
// 添加进度回调
uni.uploadFile({
// ...
progress: (res) => {
console.log('上传进度:', res.progress)
}
})
- 重试机制
let retryCount = 0
const retry = () => {
if(retryCount < 3){
retryCount++
upload(config)
}
}
- 文件分片上传
// 大文件分片处理
const chunkSize = 2 * 1024 * 1024 // 2MB分片
for(let i=0; i<Math.ceil(file.size/chunkSize); i++){
const chunk = file.slice(i*chunkSize, (i+1)*chunkSize)
uploadChunk(chunk, i)
}
典型使用场景
// 在Vue组件中的使用
import upload from '@/utils/upload'
export default {
methods: {
async handleUpload(file) {
try {
const res = await upload({
url: '/api/upload',
filePath: file.path,
name: 'avatar',
formData: {
userId: '123'
}
})
console.log('上传结果:', res)
} catch (error) {
console.error('上传失败:', error)
}
}
}
}
通过这个高度封装的upload模块,开发者可以快速实现安全可靠的文件上传功能,同时保持业务代码的简洁性。