使用Dio/Flutter(前端)与Go(后端)调用API时400错误排查
排查Flutter Dio调用Go Gin登录接口返回400的问题
1. 后端代码逻辑顺序错误
你的Go登录接口存在明显的逻辑顺序问题:在未查询数据库的情况下,直接判断刚初始化的user对象ID是否为0,而零值结构体的ID必然为0,这会导致所有请求直接返回400错误。
错误代码片段:
var user models.User // 这里user刚初始化,ID为0,直接触发返回 if user.ID == 0 { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid email and/or password", }) return } // 后续才执行数据库查询 if err := initializers.DB.Where("email = ? AND deleted_at IS NULL", body.Email).First(&user).Error; err != nil { // ... }
修复方式:将user.ID判断移至数据库查询之后(实际First方法查询失败已处理,此判断可直接删除):
// 先执行数据库查询 if err := initializers.DB.Where("email = ? AND deleted_at IS NULL", body.Email).First(&user).Error; err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid email and/or password", }) return } // 可选:已查询到用户,无需再判断ID // if user.ID == 0 { ... }
2. Flutter异步调用未等待
你的postLogin是异步函数,但调用时未添加await,导致:
- 请求未完成就打印“登录成功”,结果不准确
- 异步函数抛出的错误无法被外层
try/catch捕获
错误代码片段:
try { postLogin(emailController.text, passwordController.text); print('Login successful'); } catch (error) { // ... }
修复方式:添加await等待请求完成:
try { await postLogin(emailController.text, passwordController.text); print('Login successful'); } catch (error) { // ... }
3. 请求内容与格式排查
在Dio请求中添加日志,打印实际发送的数据和响应信息,确认请求格式是否符合后端要求:
void postLogin(String email, String password) async { Response response; // 打印请求参数 print('Login request params: email=$email, password=$password'); response = await _dio.post('$baseUrl/login', data: { 'email': email, 'password': password, }); // 打印响应详情 print('Login response code: ${response.statusCode}'); print('Login response data: ${response.data}'); }
重点确认:
emailController.text和passwordController.text是否为空- 请求的
Content-Type是否为application/json(Dio默认已设置)
4. 后端日志定位错误节点
在Go后端每个返回400的分支添加日志,明确是哪一步触发的错误:
if c.Bind(&body) != nil { log.Println("Login error: failed to parse request body") c.JSON(http.StatusBadRequest, gin.H{ "error": "Failed to read body", }) return } // 数据库查询分支添加日志 if err := initializers.DB.Where("email = ? AND deleted_at IS NULL", body.Email).First(&user).Error; err != nil { log.Printf("Login error: user not found, email=%s", body.Email) c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid email and/or password", }) return }
内容的提问来源于stack exchange,提问作者Nicholas Goldstein
相关产品推荐
相关产品推荐

