201 lines
4.3 KiB
Markdown
201 lines
4.3 KiB
Markdown
# 修复请求体为空问题
|
||
|
||
## 问题描述
|
||
|
||
七牛云上传成功后,保存文件记录到数据库时失败:
|
||
|
||
```
|
||
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
|