- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
4.1 KiB
4.1 KiB
文件上传失败问题修复报告
问题时间
2025-10-16 22:40
问题现象
用户在"编辑课程"页面上传文件时,浏览器控制台报错:
文件上传失败 - uploadRes: {file_url: '/static/uploads/courses/1/20251016224032_bac7a33f.pdf', file_name: '美拉美共建卡销售工具.pdf', file_size: 1458815, file_type: 'pdf'}
上传过程出错: Error: 文件上传失败
错误详情: {message: '文件上传失败', response: undefined, data: undefined}
关键线索:
- 文件已成功上传到服务器(有file_url等信息)
- 但uploadRes缺少
code字段 edit-course.vue:1115判断uploadRes.code === 200失败
根本原因
http.ts 的 upload() 方法存在双重数据提取问题:
-
**响应拦截器(第238行)**处理后返回:
return response.data // {code: 200, data: {file_url: '...', ...}} -
**upload方法(第392行)**又执行了:
.then((response) => response.data as ResponseData<T>) -
最终返回:
{file_url: '...', file_name: '...', file_size: ..., file_type: '...'} // 丢失了 code 字段! -
edit-course.vue 第1115行判断失败:
if (uploadRes.code === 200 && uploadRes.data) { // code 为 undefined
修复措施
1. 修复 http.ts 的 upload 方法
文件:/root/aiedu/kaopeilian-frontend/src/utils/http.ts
修改前(第392行):
}).then((response) => response.data as ResponseData<T>)
修改后:
}) // 直接返回响应拦截器处理后的结果
关键:响应拦截器已经处理了数据结构,upload方法不应再次提取 .data
2. 更新联调经验文档
文件:/root/aiedu/考培练系统规划/全链路联调/联调经验汇总.md
- 更新了第3654行的记录(2025-09-29的修复记录)
- 标记为"2025-10-16 彻底修复✅"
- 添加了详细的根因分析和修复措施
3. 更新团队基线规范
文件:/root/aiedu/考培练系统规划/全链路联调/规范与约定-团队基线.md
- 更新了"前端网络层返回结构约定"(第1285行)
- 更新了"HTTP响应拦截器规范"(第1004行)
- 添加了"具体方法实现规范",明确说明不应二次提取数据
验证结果
✅ 修复验证:
- upload方法现在正确返回
{ code: 200, data: { file_url, file_type, file_size } } edit-course.vue判断uploadRes.code === 200能够成功通过courseApi.addMaterial(...)能够正常执行- 资料列表能够即时更新
技术要点
响应拦截器与方法封装的关系
核心原则:
- 响应拦截器负责统一处理所有响应,返回标准的
{code, message, data}结构 - 具体方法只负责构造请求,不再处理响应结构
- 保持"单一职责":拦截器处理响应,方法构造请求
常见错误模式:
// ❌ 错误:双重数据提取
upload() {
return this.instance.post(url, data)
.then(res => res.data) // 响应拦截器已经返回了 {code, data}
// 再次提取 .data 会丢失 code 字段
}
正确模式:
// ✅ 正确:直接返回响应拦截器处理后的结果
upload() {
return this.instance.post(url, data) // 响应拦截器已处理
}
历史记录
- 2025-09-29:首次记录此问题,但修复不彻底
- 2025-10-16:彻底修复,更新规范文档
后续建议
- ✅ 添加单元测试覆盖 upload 方法的返回结构
- ✅ 每次修改网络层代码后,必须在浏览器中实际测试上传功能
- ✅ Code Review 时重点检查响应拦截器与方法封装的数据层级关系
- 考虑使用 TypeScript 类型检查来预防类似问题
相关文件
/root/aiedu/kaopeilian-frontend/src/utils/http.ts- 修复位置/root/aiedu/kaopeilian-frontend/src/views/manager/edit-course.vue- 调用位置/root/aiedu/考培练系统规划/全链路联调/联调经验汇总.md- 经验记录/root/aiedu/考培练系统规划/全链路联调/规范与约定-团队基线.md- 规范文档