Flutter使用Dio与Bloc时token为null 多次检查代码未定位问题
问题根因排查&修复方案
- 接口调用时机早于token赋值
你当前在Bloc实例化的同时就直接调用GetData()接口,此时如果你的token是从本地存储(如SharedPreferences)异步读取、或者是用户登录后才赋值的变量,Bloc初始化阶段token还没完成赋值,自然传入的就是null。
- 接口调用时机早于token赋值
- Authorization头格式不符合后端要求
你当前直接将token作为Authorization头的值,绝大多数后端的身份校验(尤其是JWT体系)要求头值必须带Bearer前缀,就算token有值,格式错误也会被后端判定为未携带有效身份信息,和token为null的表现一致。同时你当前的写法如果token为null,最终头值会变成字符串"null",反而会干扰后端校验逻辑。
- Authorization头格式不符合后端要求
- 缺少变量校验日志
你没有在关键节点打印token的值,无法区分是token传递过程中丢失,还是初始化阶段本身就没有赋值。
- 缺少变量校验日志
具体修复步骤
步骤1:调整Bloc初始化逻辑,确保token读取完成后再调用接口
先在你的ShopingCupit类中新增初始化方法,先读取本地存储的token,再触发接口请求:
// ShopingCupit类中新增代码 ShopingCupit(){ initToken(); } Future<void> initToken() async { // 替换为你实际存储token的本地读写逻辑 final sharedPreferences = await SharedPreferences.getInstance(); token = sharedPreferences.getString('你的token存储key') ?? ''; // token读取完成后再调用接口 GetData(); }
同步修改main中的Bloc创建代码,移除初始化时的立即调用:
providers: [ BlocProvider( create: (context) => ShopingCupit(), ), ]
步骤2:修正Dio请求头的写法
调整getData方法中的headers逻辑,增加判空和标准前缀:
static Future<Response> getData( {@required String url, String token, lang = 'ar'}) async { // 新增日志确认传入的token值 print('Dio接收的token值:$token'); dio.options.headers = { 'lang': lang, 'Authorization': token != null && token.isNotEmpty ? 'Bearer $token' : '', 'Content-Type': 'application/json', }; return await dio.get(url); }
步骤3:优化接口请求写法,避免async和then混用导致的逻辑异常
void GetData()async { emit(Loading_Data()); try { // 打印当前Bloc中的token值,排查赋值问题 print('Bloc当前token:$token'); final response = await DioHelper.getData(url: Home_, token: token); homedata = Home.fromjson(response.data); emit(Success_Data()); } catch(onError) { print(onError.toString()); emit(EROOR_Data()); } }
内容的提问来源于stack exchange,提问作者Ahmed Ragab
相关产品推荐
相关产品推荐

