Flutter使用Dio发送POST登录请求输错凭证返回403错误如何解决
问题根因
Dio 默认的响应校验规则是仅当 HTTP 状态码处于 200~299 区间时才正常返回响应对象,只要状态码超出这个范围(比如凭证错误时常见的401、400),就会直接抛出 DioError 异常,中断代码执行,所以你写的 else 分支根本不会被触发,直接报错。
解决方案
有两种常用修复方式,推荐优先用第一种加try-catch的方案,能同时覆盖网络不通、请求超时等其他异常场景:
方案1:捕获请求异常,兼容所有错误场景
修改你的 loginConect 方法如下:
Future<bool> loginConect() async { final dio = Dio(); String baseUrl = "https://soller-api-staging.herokuapp.com"; loaderRx(true); //LOADER SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); try { final response = await dio.post( baseUrl + "/auth", data: jsonEncode( { "login": emailController.text, "senha": passWordController.text, }, ), options: Options( headers: {'Content-Type': 'application/json; charset=UTF-8'}, method: "post", ), ); if (response.statusCode == 200) { await sharedPreferences.setString( "token", "string: ${response.data["string"]}", ); print("Resposta: ${response.data["string"]}"); loaderRx(false); return true; } else { print("RESPOSTA: ${response.data}"); loaderRx(false); return false; } } on DioError catch(e) { // 捕获Dio抛出的所有异常,包括状态码错误、网络不通、超时等 print("请求错误: ${e.response?.data ?? e.message}"); loaderRx(false); return false; } catch(e) { // 捕获其他未知异常 print("未知错误: $e"); loaderRx(false); return false; } }
方案2:修改Dio的validateStatus配置,让所有状态码都正常返回
如果不想用try-catch,也可以在Options里加validateStatus参数,告诉Dio所有状态码都算合法响应,不抛异常:
final response = await dio.post( baseUrl + "/auth", data: jsonEncode( { "login": emailController.text, "senha": passWordController.text, }, ), options: Options( headers: {'Content-Type': 'application/json; charset=UTF-8'}, method: "post", // 新增这一行,所有状态码都返回response,不抛异常 validateStatus: (status) => true, ), );
这种方式虽然简单,但如果遇到网络断开、请求超时这类没有状态码的异常,还是会抛错,所以建议额外加一层try-catch做兜底。
内容的提问来源于stack exchange,提问作者flavio_vieira_stack
相关产品推荐
相关产品推荐

