You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:22:52