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

Flutter使用Dio请求API报401错误无法展示接口数据问题求助

问题错误点梳理
  • 请求头设置顺序错误(直接导致401):getUserCards方法中你先执行了await dio.get(get_cards)发起请求,之后才设置Authorization请求头,请求发送时根本没有携带认证信息,所以直接返回401未授权。
  • token值未正确赋值:全局token初始硬编码为无效的字符串"token",登录接口返回的真实token你没有赋值给这个全局变量,反而在登录请求发送前就把无效的"token"存入了本地存储,所有后续请求带的都是无效token。
  • 刷新token逻辑完全不符合规范:
    • 401触发刷新逻辑时,刷新请求未携带合法的refresh_token参数,且你把Content-Type、refresh_token字段都错误拼接进了Authorization请求头中,不符合JWT认证的格式要求
    • 错误将FlutterSecureStorage实例直接赋值为token字符串,导致后续无法再通过该实例读写本地存储数据
    • 递归调用loginUser时硬传了"username"、"password"字符串,而非用户输入的真实账号密码,递归登录也必然失败
  • 接口返回值和UI层逻辑不匹配:getUserCards返回的是单个字符串值,但UI层的FutureBuilder中将返回值当做数组调用.length、通过[index]取值,就算接口请求成功也会抛出类型异常。
核心逻辑修正示例
// 修正后的getUserCards核心逻辑
Future getUserCards() async {
  try {
    // 先设置请求头再发起请求
    dio.options.headers["Authorization"] = "Bearer ${token}";
    dio.options.headers['Content-Type'] = "application/json";
    var get_cards = "https://example/api/cards";
    Response resp = await dio.get(get_cards);
    // 这里根据接口实际返回结构调整返回值,要返回数组匹配UI层
    return resp.data["list"];
  } catch (e) {
    print(e);
    rethrow;
  }
}
// 修正后的登录核心逻辑
Future loginUser(String username, String password) async {
  var storage = FlutterSecureStorage();
  var login = "https://example/users/login/";
  final data = {"username": username, "password": password};
  dio.options.headers['Content-Type'] = "application/json";
  Response response = await dio.post(login, data: data);
  if (response.statusCode == 200) {
    // 先拿返回的真实token赋值
    token = response.data["token"];
    refresh_token = response.data["refresh_token"];
    // 存到本地
    await storage.write(key: 'JWT', value: token);
    await storage.write(key: 'refreshToken', value: refresh_token);
    // 设置全局请求头
    dio.options.headers["Authorization"] = "Bearer ${token}";
    Get.to(CardScreen());
    return response.data;
  } else if (response.statusCode == 401) {
    // 刷新token逻辑
    var refreshResp = await dio.post(
      "https://example/api/cards/refresh/",
      data: {"refresh_token": refresh_token},
    );
    if (refreshResp.statusCode == 200) {
      token = refreshResp.data["token"];
      refresh_token = refreshResp.data["refresh_token"];
      await storage.write(key: 'JWT', value: token);
      dio.options.headers["Authorization"] = "Bearer ${token}";
      // 传入真实账号密码重新发起登录
      return loginUser(username, password);
    }
    return null;
  } else {
    return null;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:27:03