Flutter网络请求拦截插件intercepted_client的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter网络请求拦截插件intercepted_client的使用

intercepted_client 是一个简单的HTTP客户端,支持拦截器和并发请求。它基于 http 包构建,并实现了 Client 接口。

示例

以下是一个简单的示例,展示了如何使用 intercepted_client 添加授权头:

import 'package:http/http.dart' as http;
import 'package:intercepted_client/intercepted_client.dart';

class AuthInterceptor extends SequentialHttpInterceptor {
  final String token;

  AuthInterceptor(this.token);

  @override
  void interceptRequest(http.BaseRequest request, RequestHandler handler) {
    request.headers['Authorization'] = 'Bearer $token';
    handler.next(request);
  }
}

Future<void> main() async {
  final http.Client client = InterceptedClient(
    interceptors: [
      AuthInterceptor('my-token'),
    ],
  );

  final response = await client.get(Uri.parse('https://example.com'));

  // 打印 'Bearer my-token'
  print(response.request?.headers['Authorization']);
}

上述拦截器在每个请求中添加了一个 Authorization 头。

拦截器

拦截器是一个类,可以访问请求、响应和错误对象。它可以用于修改请求、响应或错误,或者执行任何副作用。

HttpInterceptor

HttpInterceptor 是一个简单的拦截器,定义了拦截器契约并提供了默认实现。每个请求独立处理,拦截器对前一个或下一个请求没有知识。

以下是三个可以重写的方法:

  • interceptRequest - 在请求发送之前调用,可以用于修改请求,例如添加头信息。
  • interceptResponse - 在接收到响应后调用。注意,此方法仅适用于 StreamedResponse(不适用于 Response)。这意味着你无法在此方法中看到完整的响应体,但可以访问响应头和状态码。
  • interceptError - 当请求过程中发生错误时调用。此方法可以用于重试请求或执行任何副作用。

每个方法接收一个 RequestHandlerResponseHandlerErrorHandler 对象,可以用于继续、拒绝或解决请求、响应或错误处理。

以下是一个简单的 HttpInterceptor 示例,记录请求和响应:

class LogInterceptor implements HttpInterceptor {
  @override
  void interceptRequest(http.BaseRequest request, RequestHandler handler) {
    print('Request: ${request.url}');
    handler.next(request);
  }

  @override
  void interceptResponse(http.Response response, ResponseHandler handler) {
    print('Response: ${response.statusCode}');
    handler.next(response);
  }

  @override
  void interceptError(dynamic error, ErrorHandler handler) {
    print('Error: $error');
    handler.next(error);
  }
}

SequentialHttpInterceptor

SequentialHttpInterceptor 实现了 HttpInterceptor 契约,但按顺序拦截请求。

内部维护了3个队列 - 请求、响应和错误。每个任务按顺序处理。这意味着拦截器将等待前一个任务完成后再开始下一个任务。

以下是一个示例,为每个请求添加1秒的延迟:

class DelayInterceptor extends SequentialHttpInterceptor {
  @override
  void interceptRequest(http.BaseRequest request, RequestHandler handler) {
    Future.delayed(Duration(seconds: 1), () {
      handler.next(request);
    });
  }
}

如果两个请求并行发出,第二个请求将被延迟2秒,因为它会等待前一个请求拦截器完成。

响应和错误拦截器的工作方式相同。

注意,实际的请求(数据包发送)仍然是并行的,因此应用程序不会被拦截器阻塞。

你也可以通过实现 HttpInterceptor 契约来创建自己的拦截器。

InterceptedClient

InterceptedClient 是一个实现了 http 包中的 Client 接口的类,并支持实现 HttpInterceptor 契约的拦截器。

它可以作为 http 客户端的直接替代品。

final http.Client client = InterceptedClient(
  interceptors: [
    LogInterceptor(),
  ],
);

final response = await client.get(Uri.parse('https://example.com'));

此客户端将记录每个请求和响应。

完整示例

以下是一个完整的示例,结合了 AuthInterceptorLogInterceptor

import 'package:http/http.dart' as http;
import 'package:intercepted_client/intercepted_client.dart';

class AuthInterceptor extends SequentialHttpInterceptor {
  final String token;

  AuthInterceptor(this.token);

  @override
  void interceptRequest(http.BaseRequest request, RequestHandler handler) {
    request.headers['Authorization'] = 'Bearer $token';
    handler.next(request);
  }
}

class LogInterceptor extends HttpInterceptor {
  @override
  void interceptRequest(http.BaseRequest request, RequestHandler handler) {
    print('Request: ${request.url}');
    handler.next(request);
  }

  @override
  void interceptResponse(http.StreamedResponse response, ResponseHandler handler) {
    print('Request: ${handler.request.url} - Status: ${response.statusCode}');
    handler.resolveResponse(response);
  }

  @override
  void interceptError(Object error, ErrorHandler handler) {
    print('Error: $error');
    handler.rejectError(error);
  }
}

Future<void> main() async {
  final http.Client client = InterceptedClient(
    interceptors: [
      AuthInterceptor('my-token'),
      LogInterceptor(),
    ],
  );

  final response = await client.get(Uri.parse('https://example.com'));

  // 打印 'Bearer my-token'
  print(response.request?.headers['Authorization']);
}

希望这些内容能帮助你更好地理解和使用 intercepted_client 插件。如果有任何问题或需要进一步的帮助,请随时提问!


更多关于Flutter网络请求拦截插件intercepted_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络请求拦截插件intercepted_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用intercepted_client插件来进行网络请求拦截的示例代码。intercepted_client是一个允许你拦截HTTP请求和响应的Flutter插件,非常适用于日志记录、请求修改、错误处理等场景。

首先,确保你的pubspec.yaml文件中已经添加了intercepted_client依赖:

dependencies:
  flutter:
    sdk: flutter
  intercepted_client: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们编写一个示例,展示如何使用intercepted_client进行网络请求拦截。

示例代码

  1. 创建一个拦截器类
import 'package:intercepted_client/intercepted_client.dart';
import 'dart:convert';

class LoggingInterceptor implements RequestInterceptor, ResponseInterceptor {
  @override
  Future<Request> interceptRequest(Request request) async {
    print('Sending request:');
    print('Method: ${request.method}');
    print('URL: ${request.url}');
    if (request.body != null) {
      print('Body: ${utf8.decode(request.body!)}');
    }
    return request;
  }

  @override
  Future<Response> interceptResponse(Response response, Request request) async {
    print('Received response:');
    print('Status code: ${response.statusCode}');
    if (response.bodyBytes != null) {
      print('Body: ${utf8.decode(response.bodyBytes!)}');
    }
    return response;
  }
}
  1. 配置客户端并使用拦截器
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:intercepted_client/intercepted_client.dart';
import 'logging_interceptor.dart';  // 假设你将拦截器类放在这个文件中

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Intercepted Client Example'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: fetchData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  return Text('Data: ${snapshot.data!}');
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }

  Future<String> fetchData() async {
    final client = InterceptedClient.build(
      baseClient: http.Client(),
      requestInterceptors: [LoggingInterceptor()],
      responseInterceptors: [LoggingInterceptor()],
    );

    try {
      final response = await client.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
      if (response.statusCode == 200) {
        return utf8.decode(response.bodyBytes!);
      } else {
        throw Exception('Failed to load data');
      }
    } finally {
      client.close();
    }
  }
}

解释

  1. 拦截器类LoggingInterceptor类实现了RequestInterceptorResponseInterceptor接口,用于拦截请求和响应。在拦截请求时,它打印了请求方法、URL和请求体。在拦截响应时,它打印了状态码和响应体。

  2. 配置客户端:在fetchData方法中,我们创建了一个InterceptedClient实例,并传入了一个基本的http.Client实例以及我们的拦截器列表。然后,我们使用这个客户端来发送GET请求。

  3. 使用拦截器:在Flutter应用中,我们使用FutureBuilder来异步获取数据并显示。

这个示例展示了如何使用intercepted_client插件来拦截和记录HTTP请求和响应。你可以根据需要扩展拦截器的功能,比如添加认证头、修改请求体、处理错误等。

回到顶部