Flutter Dio拦截器的高级用法

在Flutter中使用Dio拦截器时,如何实现以下高级功能?

  1. 如何动态修改请求头(如根据Token过期自动刷新并更新Authorization)?
  2. 怎样统一处理特定错误码(如401跳登录页)而不重复写判断逻辑?
  3. 拦截器中如何优雅地实现请求重试机制(比如超时自动重试3次)?
  4. 有没有办法在拦截器层级实现全局Loading控制,避免每个请求单独处理?
  5. 遇到文件上传/下载时,拦截器里的数据转换有哪些注意事项?
    希望能结合具体代码示例说明最佳实践!
3 回复

在Flutter中使用Dio进行网络请求时,拦截器是非常强大的功能。高级用法包括:

  1. 请求日志:记录每次请求的详细信息,如URL、参数等,便于调试和监控。

    dio.interceptors.add(InterceptorsWrapper(
        onRequest: (options, handler) {
          print('REQUEST[${options.method}] => PATH: ${options.path}');
          return handler.next(options);
        },
        onResponse: (response, handler) {
          print('RESPONSE[${response.statusCode}]');
          return handler.next(response);
        },
        onError: (DioError e, handler) {
          print('ERROR[${e.response?.statusCode}]');
          return handler.next(e);
        }
    ));
    
  2. 统一添加Token:在每个请求头中自动注入认证信息。

    final token = 'your_token_here';
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        options.headers['Authorization'] = 'Bearer $token';
        return handler.next(options);
      },
    ));
    
  3. 自动重试失败请求:在网络异常时自动重试。

    dio.interceptors.add(RetryInterceptor(
      dio: dio,
      retries: 3,
      retryDelay: (attempt) => Duration(seconds: attempt),
    ));
    
  4. 处理响应数据:统一格式化返回的数据。

    dio.interceptors.add(InterceptorsWrapper(
      onResponse: (response, handler) {
        // 假设后端返回的数据格式为 {data: {...}, code: 200}
        if (response.data['code'] == 200) {
          response.data = response.data['data'];
        }
        return handler.next(response);
      },
    ));
    

这些高级用法可以让Dio更加灵活和强大,满足复杂项目的需求。

更多关于Flutter Dio拦截器的高级用法的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Flutter 中 Dio 的拦截器非常强大,可以用于统一处理请求和响应。以下是一些高级用法:

  1. 添加请求头:在拦截器中统一设置 Token 或其他公共参数。

    dio.interceptors.add(InterceptorsWrapper(
        onRequest: (options, handler) {
          options.headers['Authorization'] = 'Bearer $token';
          return handler.next(options);
        }
    ));
    
  2. 请求日志记录:方便调试。

    dio.interceptors.add(LoggingInterceptor());
    class LoggingInterceptor extends Interceptor {
      @override
      void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
        print('REQUEST[${options.method}] ${options.path}');
        super.onRequest(options, handler);
      }
    }
    
  3. 统一处理错误:如网络异常或服务器返回的错误码。

    dio.interceptors.add(InterceptorsWrapper(
        onResponse: (response, handler) {
          if (response.statusCode! >= 400) {
            // 自定义错误处理
            throw Exception('Error: ${response.statusCode}');
          }
          return handler.next(response);
        }
    ));
    
  4. 自动重试机制:处理网络波动导致的失败。

    dio.interceptors.add(RetryInterceptor(
        dio: dio,
        retries: 3,
        retryDelays: const Duration(seconds: 2),
    ));
    

通过这些高级用法,你可以更高效地管理网络请求,提升代码的可维护性。

Flutter中Dio拦截器的高级用法主要包括以下几种场景:

  1. 请求/响应加解密
dio.interceptors.add(InterceptorsWrapper(
  onRequest: (options, handler) {
    // 请求数据加密
    options.data = encryptData(options.data);
    return handler.next(options);
  },
  onResponse: (response, handler) {
    // 响应数据解密
    response.data = decryptData(response.data);
    return handler.next(response);
  }
));
  1. 动态Token刷新
dio.interceptors.add(QueuedInterceptorsWrapper(
  onError: (error, handler) async {
    if (error.response?.statusCode == 401) {
      final newToken = await refreshToken();
      dio.options.headers['Authorization'] = 'Bearer $newToken';
      return handler.resolve(await dio.request(error.requestOptions.path));
    }
    return handler.next(error);
  }
));
  1. 请求重试机制
dio.interceptors.add(RetryInterceptor(
  dio: dio,
  retries: 3,
  retryDelays: const [
    Duration(seconds: 1),
    Duration(seconds: 2),
    Duration(seconds: 3),
  ],
));
  1. 日志精细化处理
dio.interceptors.add(LogInterceptor(
  requestBody: true,
  responseBody: true,
  logPrint: (obj) {
    // 自定义日志输出方式
    debugPrint(obj.toString());
  }
));
  1. 缓存拦截器
dio.interceptors.add(
  CacheInterceptor(
    store: MemCacheStore(),
    policy: CachePolicy.requestForceCache
  )
);

高级技巧:

  • 使用QueuedInterceptorsWrapper防止并发问题
  • 多个拦截器按添加顺序执行
  • 通过handler.reject/handler.resolve中断流程
  • 结合CancelToken实现请求取消

建议根据实际需求组合使用这些拦截器,注意拦截器顺序会影响处理流程。

回到顶部