为啥flutter dio拦截器不调用该方法?

Posted

技术标签:

【中文标题】为啥flutter dio拦截器不调用该方法?【英文标题】:Why does flutter dio interceptor not invoking the method?为什么flutter dio拦截器不调用该方法? 【发布时间】:2021-06-20 06:22:36 【问题描述】:

我正在开发一个使用 JWT 访问后端端点的颤振应用程序。 当访问令牌过期时,我根据此处提供的解决方案添加了一个拦截器来刷新令牌: Using Interceptor in Dio for Flutter to Refresh Token 我可以看到显示 401 的服务器日志。

这是我的代码:

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:dummy/utils/config.dart';

Future<Response> uploadVideo(filePath, fileName, title, jwt) async 
  Dio dio = new Dio();
  var token = json.decode(jwt);
  dio.interceptors.clear();

  dio.options.headers["Authorization"] = "Bearer $token['access']";
  dio.interceptors.add(InterceptorsWrapper(onError: (error) async 
    print(error.response);
    if (error.response?.statusCode == 403 ||
     error.response?.statusCode == 401) 
    await refreshToken(jwt);
    _retry(error.request, dio);
     
    return error.response;
  ));
  Response response;
  try 
    FormData formData = FormData.fromMap(
      "file_name": fileName,
      "content": await MultipartFile.fromFile(filePath),
      'title': title,
    );
    response = await dio.post("$BASE_URL/video/create/", data: formData);
    return response;
   on DioError catch (e) 
    if (e.response) 
      print(e.response.data);
      print(e.response.headers);
      print(e.response.request);
     else 
      // Something happened in setting up or sending the request that triggered an Error
      print(e.request);
      print(e.message);
    
    return e.response;
  


Future<Response<dynamic>> _retry(RequestOptions requestOptions, Dio dio) async 
  final options = new Options(
    method: requestOptions.method,
    headers: requestOptions.headers,
  );
  return dio.request<dynamic>(requestOptions.path,
      data: requestOptions.data,
      queryParameters: requestOptions.queryParameters,
      options: options);


Future<Response> refreshToken(jwt) async 
  print("COMING INSIDE");
  Dio dio = new Dio();
  var token = json.decode(jwt);
  var refreshToken = token['refresh'];
  Response response;
  try 
    FormData formData = FormData.fromMap(
      "refresh": refreshToken,
    );
    response = await dio.post("$BASE_URL/auth/login/refresh/", data: formData);
    return response;
   catch (e) 
    return e.response;
  

我也尝试使用调试器,但它没有在检查 401 和 403 的 if 语句之后执行代码。服务器清楚地给出了 401,因为我在本地运行它,所以我可以看到日志。

我在这里做错了什么?

提前致谢。

【问题讨论】:

能否提供print(error.response);的输出示例? 嗨,我收到这个 `DioError [DioErrorType.DEFAULT]: SocketException: OS Error: Broken pipe, errno = 32, address = 172.22.22.55, port = 47164.response ` 我可以确认应用程序到达后端服务器,登录和注册屏幕都可以正常工作。 升级到 dio 4 时是否发生这种情况? 毫无疑问,但没有回复。在可以读取响应之前关闭套接字,写入超时等等。 SocketException: OS Error: Broken pipe, errno = 32 是你的问题。你需要在那里调查,我认为这里没有人可以帮助你。 【参考方案1】:

我认为问题出在你的拦截器上:

dio.interceptors.add(InterceptorsWrapper(onError: (error) async 
    print(error.response);
    if (error.response?.statusCode == 403 ||
     error.response?.statusCode == 401) 
    await refreshToken(jwt);
    _retry(error.request, dio);
     
    return error.response;
  ));

你正在调用重试方法,但是:

您无需等待结果; 你还是返回了一个错误。

尝试在_retry 之前添加return

dio.interceptors.add(InterceptorsWrapper(onError: (error) async 
    print(error.response);
    if (error.response?.statusCode == 403 ||
     error.response?.statusCode == 401) 
    await refreshToken(jwt);
    return _retry(error.request, dio);
     
    return error.response;
  ));

【讨论】:

您好,感谢您的回复。如果执行到达 if 块,我认为可能是这种情况,但由于状态码不存在。

以上是关于为啥flutter dio拦截器不调用该方法?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 如何处理401 未授权的 Dio 拦截器

Flutter--网络请求dio封装网络请求框架

技惊四座的Flutter丨网络请求框架 dio

赠书|Flutter-dio封装,满足你的需要

flutter网络dio框架公共请求参数请求header使用总结

Flutter实现网络请求