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

Flutter中如何通过登录API返回结果校验用户账号密码正确性

Flutter登录接口校验与错误提示实现方案

现有代码存在两个核心问题:

  • 异步请求未做等待处理:createAlbum是异步Future方法,你在onPressed中直接赋值后立即判断,此时接口请求尚未返回,无法拿到结果做校验
  • 视图操作耦合在请求方法中:把页面跳转逻辑直接写在网络请求方法里,不利于错误逻辑统一处理,且方法内部直接使用context容易引发上下文失效问题

第一步:改造网络请求方法

把跳转逻辑从createAlbum中移除,只保留网络请求和结果返回,错误场景抛出明确的异常信息:

Future<Album> createAlbum(String employee_custom_id, String password) async {
  final response = await http.post(
    Uri.parse('https://portal-api.jomakhata.com/api/auth/login'),
    headers: <String, String>{
      'Content-Type': 'application/json',
    },
    body: jsonEncode(<String, String>{
      'employee_custom_id': employee_custom_id,
      'password': password,
    }),
  );
  final data = json.decode(response.body);
  if (response.statusCode == 200) {
    // 判断业务返回是否为登录成功状态
    if(data['message'] == 'success'){
      saveToken(data);
      return Album.fromJson(data);
    }else{
      // 抛出业务错误,比如账号密码不匹配
      throw Exception(data['message'] ?? '账号或密码错误');
    }
  } else {
    throw Exception(data['message'] ?? '登录失败,请稍后重试');
  }
}

第二步:改造登录按钮点击逻辑

给onPressed添加async修饰,用try-catch捕获请求结果,成功时跳转主页,失败时弹出提示:

child: RaisedButton(
  child: Text('Login'),
  onPressed: () async { // 添加async修饰支持异步等待
    String _email = _emailController.text.trim();
    String _password = _passwordController.text.trim();
    // 本地非空预校验,减少无效接口请求
    if(_email.isEmpty || _password.isEmpty){
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('账号和密码不能为空'))
      );
      return;
    }
    setState(() {
      // 可在此处添加加载状态标识,比如展示加载弹窗
    });
    try{
      // 等待异步请求返回结果
      _futureAlbum = await createAlbum(_email, _password);
      // 请求成功跳转主页,加mounted判断防止页面销毁后操作上下文报错
      if(mounted){
        Navigator.of(context).pushAndRemoveUntil(
          MaterialPageRoute(builder: (BuildContext context) => const Main()),
          (Route<dynamic> route) => false
        );
      }
    }catch(e){
      // 捕获异常弹出错误提示
      if(mounted){
        // 系统自带SnackBar提示方案
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(e.toString().replaceAll('Exception: ', '')))
        );
        // 若使用toast提示可接入fluttertoast包,调用代码如下:
        // Fluttertoast.showToast(msg: e.toString().replaceAll('Exception: ', ''));
      }
    }finally{
      if(mounted){
        setState(() {
          // 隐藏加载状态
        });
      }
    }
  },
  color: Colors.green,
  textColor: Colors.white,
  padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
),

补充说明

  • mounted判断用于避免页面销毁后操作上下文引发的异常
  • 本地非空校验可以减少无效的网络请求,提升交互体验
  • 错误提示文案直接取接口返回的message字段,和后端错误逻辑保持一致,不需要前端硬编码匹配规则

内容的提问来源于stack exchange,提问作者Fozuda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:48:04