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

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)永远不会执行。

解决方案

  1. 配置Dio的validateStatus参数,让它不把404、400当作异常抛出,使这些状态码的响应能进入try块的状态判断逻辑
  2. 使用全局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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:00:25