GetX控制器路由异常:404响应时无法跳转页面求助
问题:GetX控制器中Dio请求404/400状态码分支逻辑不执行,路由跳转失败
在Flutter项目中使用GetX控制器开发时,调用POST接口后仅200状态码的分支逻辑能正常执行,404或400状态码对应的逻辑完全不生效。尝试在404响应时用Get.to()或Navigator.push()跳转到EmailScreen页面,均失败。
相关代码:
import 'package:bms/constant/api_constant.dart'; import 'package:bms/view/main/main_page.dart'; import 'package:bms/view/register/email_screen.dart'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; class AuthStep1Controler extends GetxController { TextEditingController emailController = TextEditingController(); TextEditingController passwordController = TextEditingController(); final Rx op = 0.0.obs; final RxBool visible = false.obs; checkEmail() async { try { var response = await Dio().post(ApiUrlConstant.checkEmail, data: { "email": emailController.text, }); if (response.statusCode == 404) { Get.to(const EmailScreen()); } else if (response.statusCode == 200) { Future.delayed(const Duration(seconds: 2), () { op.value = 1.0; visible.value = true; }); } else if (response.statusCode == 400) { debugPrint(response.toString()); } } catch (e) { if (e is DioException) { debugPrint(e.toString()); } } } }
问题原因
Dio默认会将非2xx状态码的响应抛出异常,因此404、400这类状态码不会进入try块内的状态码判断分支,而是直接走到catch块,导致你写的if(response.statusCode ==404)永远不会执行。
解决方案
- 配置Dio的
validateStatus参数,让它不把404、400当作异常抛出,使这些状态码的响应能进入try块的状态判断逻辑 - 使用全局Dio实例统一管理配置,避免重复创建实例
修复后的代码
import 'package:bms/constant/api_constant.dart'; import 'package:bms/view/main/main_page.dart'; import 'package:bms/view/register/email_screen.dart'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; class AuthStep1Controler extends GetxController { TextEditingController emailController = TextEditingController(); TextEditingController passwordController = TextEditingController(); final Rx op = 0.0.obs; final RxBool visible = false.obs; // 初始化全局Dio实例,统一配置状态码规则 final Dio _dio = Dio(BaseOptions( validateStatus: (status) { // 允许2xx、400、404状态码不抛出异常 return status != null && (status >= 200 && status < 300 || status == 400 || status == 404); }, )); checkEmail() async { try { var response = await _dio.post(ApiUrlConstant.checkEmail, data: { "email": emailController.text, }); if (response.statusCode == 404) { Get.to(() => const EmailScreen()); } else if (response.statusCode == 200) { Future.delayed(const Duration(seconds: 2), () { op.value = 1.0; visible.value = true; }); } else if (response.statusCode == 400) { debugPrint(response.toString()); } } catch (e) { if (e is DioException) { debugPrint(e.toString()); } } } }
关键说明
validateStatus是Dio的核心配置项,自定义哪些状态码需要被视为成功响应(不抛出异常),这里指定200-299、400、404都不触发异常,确保这些状态码的响应能进入try块的判断逻辑- 使用全局Dio实例替代每次请求新建实例,便于后续统一添加拦截器、超时时间等配置
Get.to(() => const EmailScreen())的写法比直接传const EmailScreen()更稳妥,确保Widget能正确初始化并关联上下文
内容的提问来源于stack exchange,提问作者Amin Khademi
相关产品推荐
相关产品推荐

