修复七牛云上传bug

This commit is contained in:
李志强 2026-04-09 19:27:47 +08:00
parent f4403701c1
commit ea0e84c93c
6 changed files with 551 additions and 0 deletions

View File

@ -2,6 +2,9 @@ appname = server
httpport = 8081
runmode = dev
# 启用请求体复制(允许多次读取请求体)
copyrequestbody = true
# 服务器超时配置(支持大文件上传)
# 0 表示不设置超时限制
ServerTimeOut = 0

View File

@ -126,6 +126,11 @@ func (c *QiniuUploadController) SaveFileRecord() {
}
tid := c.effectiveTid(claims)
// 调试:打印请求体
body := c.Ctx.Input.RequestBody
fmt.Println("SaveFileRecord 请求体长度:", len(body))
fmt.Println("SaveFileRecord 请求体内容:", string(body))
// 解析请求参数
type SaveRequest struct {
Key string `json:"key"` // 七牛云文件 key

View File

@ -0,0 +1,200 @@
# 修复请求体为空问题
## 问题描述
七牛云上传成功后,保存文件记录到数据库时失败:
```
POST https://api.yunzer.cn/platform/qiniu/save 400
{"code": 400, "msg": "参数解析失败: 请求体为空"}
```
## 问题原因
Beego 框架默认不会复制请求体到 `c.Ctx.Input.RequestBody`,需要显式启用 `CopyRequestBody` 配置。
## 解决方案
### 1. 修改 go/conf/app.conf
添加配置:
```properties
# 启用请求体复制(允许多次读取请求体)
copyrequestbody = true
```
### 2. 修改 go/main.go
在代码中显式启用:
```go
func main() {
// 初始化数据库
models.Init(version.Version)
// 启用请求体复制(允许多次读取请求体)
beego.BConfig.CopyRequestBody = true // ← 新增
// 设置最大请求体大小10MB足够登录请求使用
beego.BConfig.MaxMemory = 10 << 20 // 10MB
// 静态资源:映射 /uploads 到本地 uploads 目录,供前端访问上传文件
beego.SetStaticPath("/uploads", "uploads")
beego.Run()
}
```
### 3. 添加调试日志
`go/controllers/qiniu_upload.go``SaveFileRecord` 方法中添加日志:
```go
// 调试:打印请求体
body := c.Ctx.Input.RequestBody
fmt.Println("SaveFileRecord 请求体长度:", len(body))
fmt.Println("SaveFileRecord 请求体内容:", string(body))
```
## 重启服务
```bash
# 重启 Go 服务
systemctl restart go-api
# 查看服务状态
systemctl status go-api
# 查看日志
tail -f /www/wwwroot/api.yunzer.cn/go.log
```
## 测试步骤
1. 重启后端服务
2. 登录前端系统
3. 进入软件升级页面
4. 上传一个文件
5. 观察后端日志
### 预期日志输出
```
SaveFileRecord 请求体长度: 123
SaveFileRecord 请求体内容: {"key":"2026/04/09/xxx.exe","hash":"xxx","size":60742452,"name":"xxx.exe","mimeType":"application/x-msdownload","cate":0}
```
### 预期响应
```json
{
"code": 200,
"data": {
"url": "http://7colud.yunzer.cn/2026/04/09/xxx.exe",
"id": 123,
"name": "xxx.exe",
"key": "2026/04/09/xxx.exe"
}
}
```
## 相关配置说明
### CopyRequestBody 的作用
Beego 框架中,请求体默认只能读取一次。如果需要在多个地方读取请求体(例如中间件和控制器),需要启用 `CopyRequestBody`
启用后Beego 会在接收到请求时将请求体复制到 `c.Ctx.Input.RequestBody`,允许多次读取。
### 配置方式
有两种方式启用:
1. **配置文件方式** (`go/conf/app.conf`):
```properties
copyrequestbody = true
```
2. **代码方式** (`go/main.go`):
```go
beego.BConfig.CopyRequestBody = true
```
建议两种方式都配置,确保生效。
## 注意事项
### 1. 内存占用
启用 `CopyRequestBody` 会增加内存占用,因为每个请求的请求体都会被复制到内存中。
对于大文件上传,建议:
- 使用七牛云直传(不经过服务器)
- 只在需要的接口启用请求体复制
### 2. 与登录接口的兼容性
之前修复登录问题时,我们已经将登录接口改为使用 `c.Ctx.Input.RequestBody`,启用 `CopyRequestBody` 后,登录接口也能正常工作。
### 3. MaxMemory 配置
`MaxMemory` 配置控制请求体的最大大小:
```go
beego.BConfig.MaxMemory = 10 << 20 // 10MB
```
对于七牛云直传,文件不经过服务器,所以这个限制不影响大文件上传。
## 验证修复
### 1. 检查配置是否生效
重启服务后,查看日志中是否有请求体内容输出。
### 2. 测试上传功能
上传一个文件,检查:
- 七牛云上传是否成功
- 数据库记录是否保存成功
- 文件 URL 是否正确
### 3. 检查数据库
```sql
SELECT id, name, src, size, type, cate, md5, create_time
FROM system_file
ORDER BY id DESC
LIMIT 5;
```
应该能看到新上传的文件记录。
## 回滚方案
如果修复后出现其他问题,可以临时禁用:
```go
// go/main.go
beego.BConfig.CopyRequestBody = false
```
或在 `go/conf/app.conf` 中:
```properties
copyrequestbody = false
```
然后重启服务。
## 相关文件
- `go/main.go` - 主程序入口
- `go/conf/app.conf` - 配置文件
- `go/controllers/qiniu_upload.go` - 七牛云上传控制器
- `go/controllers/platform_auth.go` - 登录控制器(也使用 RequestBody
## 更新日期
2026-04-09

View File

@ -0,0 +1,122 @@
# 快速修复:请求体为空问题
## 问题
```
POST /platform/qiniu/save 400
{"code": 400, "msg": "参数解析失败: 请求体为空"}
```
## 快速修复步骤
### 1. 重启后端服务(已修改配置)
```bash
systemctl restart go-api
```
### 2. 查看服务状态
```bash
systemctl status go-api
```
预期输出:
```
● go-api.service - Go API Server
Loaded: loaded
Active: active (running)
```
### 3. 查看日志
```bash
tail -f /www/wwwroot/api.yunzer.cn/go.log
```
### 4. 测试上传
1. 登录系统
2. 进入软件升级页面
3. 上传一个文件
### 5. 观察日志输出
应该看到:
```
SaveFileRecord 请求体长度: xxx
SaveFileRecord 请求体内容: {"key":"...","hash":"...","size":...}
```
## 已修改的文件
`go/main.go` - 添加 `beego.BConfig.CopyRequestBody = true`
`go/conf/app.conf` - 添加 `copyrequestbody = true`
`go/controllers/qiniu_upload.go` - 添加调试日志
## 如果还是失败
### 检查 1: 服务是否重启成功
```bash
systemctl status go-api
```
如果失败,查看错误:
```bash
journalctl -u go-api -n 50
```
### 检查 2: 配置是否生效
查看日志中是否有请求体内容输出。如果没有,说明配置未生效。
### 检查 3: 前端请求是否正确
打开浏览器开发者工具,查看 Network 标签:
- 请求方法POST
- Content-Type: application/json
- 请求体:应该有 JSON 数据
## 完整上传流程
```
1. 前端上传文件到七牛云 ✓
2. 七牛云返回文件信息 ✓
{
"key": "2026/04/09/xxx.exe",
"hash": "xxx",
"size": 60742452
}
3. 前端调用 /platform/qiniu/save ← 这里失败了
POST /platform/qiniu/save
Body: {
"key": "...",
"hash": "...",
"size": ...,
"name": "...",
"mimeType": "...",
"cate": 0
}
4. 后端保存到数据库 ← 修复后应该成功
5. 返回文件 URL
```
## 修复原理
Beego 框架默认不复制请求体,需要启用 `CopyRequestBody`
```go
// 修复前
c.Ctx.Input.RequestBody // 空的
// 修复后(启用 CopyRequestBody
c.Ctx.Input.RequestBody // 包含请求体数据
```
## 更新时间
2026-04-09

View File

@ -0,0 +1,218 @@
# 立即执行:重启服务
## 修复内容
✅ 已修复日志错误(`beego.Info` → `fmt.Println`
✅ 已启用 `CopyRequestBody` 配置
✅ 已添加调试输出
## 立即执行
### 1. 重启服务
```bash
systemctl restart go-api
```
### 2. 检查服务状态
```bash
systemctl status go-api
```
**预期输出**:
```
● go-api.service - Go API Server
Active: active (running)
```
如果显示 `failed`,查看错误:
```bash
journalctl -u go-api -n 50
```
### 3. 查看实时日志
```bash
tail -f /www/wwwroot/api.yunzer.cn/go.log
```
或者查看标准输出(调试日志会输出到这里):
```bash
journalctl -u go-api -f
```
### 4. 测试上传
1. 打开浏览器,登录系统
2. 进入:平台管理 → 软件升级
3. 点击"新增"或"编辑"
4. 上传一个文件(建议先用小文件测试)
### 5. 观察日志
在终端中应该看到:
```
SaveFileRecord 请求体长度: 150
SaveFileRecord 请求体内容: {"key":"2026/04/09/1775732976777726699.exe","hash":"loozoz7qv9flWXsS5UldWdPX9-T_","size":60742452,"name":"xxx.exe","mimeType":"application/x-msdownload","cate":0}
```
### 6. 验证结果
**前端应该显示**:
- 上传进度条
- 上传成功提示
- 文件 URL: `http://7colud.yunzer.cn/2026/04/09/xxxxx.exe`
**数据库验证**:
```bash
mysql -u go-platform -p -h 212.64.112.158 -P 3388 go-platform
```
```sql
SELECT id, name, src, size, type, create_time
FROM system_file
ORDER BY id DESC
LIMIT 5;
```
## 完整上传流程
```
用户选择文件
前端获取存储配置
storageType: 'qiniu'
前端获取上传凭证
token, region: 'z2'
前端直接上传到七牛云
POST https://upload-z2.qiniup.com
✓ 成功返回: {key, hash, size}
前端保存文件记录
POST /platform/qiniu/save
Body: {key, hash, size, name, mimeType, cate}
后端接收请求
✓ CopyRequestBody 已启用
✓ 请求体不为空
后端保存到数据库
INSERT INTO system_file
返回文件信息
{url, id, name, key}
前端显示上传成功
```
## 如果还是失败
### 问题 1: 服务启动失败
**检查**:
```bash
journalctl -u go-api -n 50
```
**常见原因**:
- 端口被占用
- 数据库连接失败
- 配置文件错误
### 问题 2: 请求体仍然为空
**检查**:
1. 确认服务已重启
2. 查看日志中是否有 "请求体长度: 0"
3. 检查前端请求的 Content-Type 是否为 `application/json`
**解决**:
```bash
# 确保配置生效
grep -i "copyrequestbody" /www/wwwroot/api.yunzer.cn/conf/app.conf
# 应该看到
copyrequestbody = true
```
### 问题 3: 七牛云上传失败
**检查**:
- 浏览器控制台是否有 CORS 错误
- 七牛云 bucket 是否存在
- 区域配置是否正确z2
**解决**:
参见 `platform/docs/七牛云上传测试步骤.md`
## 调试技巧
### 1. 查看完整请求
浏览器开发者工具 → Network 标签 → 找到 `/platform/qiniu/save` 请求:
- Headers: 查看 Content-Type
- Payload: 查看请求体内容
- Response: 查看响应内容
### 2. 查看后端日志
```bash
# 实时日志
tail -f /www/wwwroot/api.yunzer.cn/go.log
# 或者查看 systemd 日志(包含 fmt.Println 输出)
journalctl -u go-api -f
```
### 3. 测试 API
使用 curl 测试:
```bash
# 获取 token先登录
TOKEN="your_token_here"
# 测试保存接口
curl -X POST https://api.yunzer.cn/platform/qiniu/save \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "test/test.txt",
"hash": "test123",
"size": 1024,
"name": "test.txt",
"mimeType": "text/plain",
"cate": 0
}'
```
## 成功标志
✓ 服务启动成功
✓ 日志中看到请求体内容
✓ 前端显示上传成功
✓ 数据库有新记录
✓ 文件 URL 可以访问
## 下一步
上传成功后,可以:
1. 移除调试日志(`fmt.Println`
2. 测试大文件上传
3. 测试批量上传
4. 验证文件去重功能
## 联系支持
如果问题仍然存在,请提供:
1. 服务状态输出
2. 完整的错误日志
3. 浏览器控制台截图
4. 请求和响应的详细信息
## 更新时间
2026-04-09

View File

@ -12,6 +12,9 @@ func main() {
// 初始化数据库
models.Init(version.Version)
// 启用请求体复制(允许多次读取请求体)
beego.BConfig.CopyRequestBody = true
// 设置最大请求体大小10MB足够登录请求使用
beego.BConfig.MaxMemory = 10 << 20 // 10MB