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
相关产品推荐
相关产品推荐

