Flutter网络请求拦截插件http_intercept的使用
Flutter网络请求拦截插件http_intercept的使用
安装
对于Dart
运行以下命令:
dart pub add http_intercept
对于Flutter
运行以下命令:
flutter pub add http_intercept
使用
要使用http_intercept
插件,你需要创建一个HttpInterceptorWrapper
实例,并将其与你的HTTP客户端一起使用。以下是一个基本示例:
对于Dart
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:http_intercept/http_intercept.dart';
void main() {
unawaited(
http.runWithClient(
_myDartApp,
() => HttpClientProxy(
interceptors: [
HttpInterceptorWrapper(
onRequest: (requestOptions) {
// 添加自定义头部或修改请求
requestOptions.headers['Authorization'] = 'Bearer YOUR_TOKEN';
return OnRequest.next(requestOptions);
},
),
],
),
),
);
}
Future<void> _myDartApp() async {
final client = http.Client();
final response = await client.get(Uri.parse('https://jsonplaceholder.typicode.com/data'));
print(response.body);
}
对于Flutter
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_intercept/http_intercept.dart';
void main() {
unawaited(
http.runWithClient(
() {
runApp(const MyApp());
},
() => HttpClientProxy(
interceptors: [
HttpInterceptorWrapper(
onRequest: (requestOptions) {
// 添加自定义头部或修改请求
requestOptions.headers['Authorization'] = 'Bearer YOUR_TOKEN';
return OnRequest.next(requestOptions);
},
),
],
),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
// 在这里添加你的代码
}
}
高级用法
对于更高级的用法,你可以链式多个拦截器,处理特定的错误类型,或者在响应到达应用之前对其进行修改。以下是一个示例:
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:http_intercept/http_intercept.dart';
class LoggingInterceptor extends HttpInterceptor {
[@override](/user/override)
FutureOr<OnRequest> onRequest(http.BaseRequest request) {
print('Request: ${request.method} ${request.url}');
return OnRequest.next(request);
}
[@override](/user/override)
FutureOr<OnResponse> onResponse(http.StreamedResponse response) {
print('Response: ${response.statusCode}');
return OnResponse.next(response);
}
[@override](/user/override)
FutureOr<OnError> onError(
http.BaseRequest request,
Object error,
StackTrace? stackTrace,
) {
print('Error: $error');
return OnError.next(request, error, stackTrace);
}
}
void main() {
unawaited(
http.runWithClient(
_myDartApp,
() => HttpClientProxy(
interceptors: [
LoggingInterceptor(),
// 其他拦截器
],
),
),
);
}
Future<void> _myDartApp() async {
final client = http.Client();
final response = await client.get(Uri.parse('https://jsonplaceholder.typicode.com/data'));
print(response.body);
}
兼容性
http_intercept
可以与流行的HTTP包如Chopper
、Retrofit
和Dio
配合使用。你也可以与其他HTTP客户端结合使用,如cupertino_http
用于iOS和macOS,cronet_http
用于Android,以及RetryClient
,这些都与http
包兼容。这使得它易于集成到各种项目和设置中。
Flutter的Image小部件注意事项
http_intercept
不会直接与Flutter的Image.network
小部件一起工作,因为Image.network
小部件使用的NetworkImage
依赖于dart:io
包中的HttpClient
。然而,你可以通过使用http_image_provider
包来实现这一功能,该包允许你将http
包与Image
小部件一起使用,从而启用http_intercept
。
使用Chopper
要使用http_intercept
与Chopper,你需要创建一个HttpClientProxy
实例并传递给Chopper客户端。以下是一个示例:
import 'dart:async';
import 'package:chopper/chopper.dart';
import 'package:http_intercept/http_intercept.dart';
part 'main_chopper.chopper.dart';
Future<void> main() async {
// 创建一个带有拦截器的HttpClientProxy实例。
final httpClient = HttpClientProxy(
interceptors: [
HttpInterceptorWrapper(
onRequest: (request) {
// 向请求添加自定义头部。
request.headers['customHeader'] = 'customHeaderValue';
return OnRequest.next(request);
},
),
],
);
// 使用带有拦截器的自定义HttpClient创建一个ChopperClient。
// 这允许Chopper使用带有拦截器的自定义HTTP客户端而不是默认的HTTP客户端。
final chopper = ChopperClient(
client: httpClient,
services: [PostsService.create()],
);
// 获取PostsService的实例。
final postsService = chopper.getService<PostsService>();
// 发送GET请求以获取ID为'1'的帖子。
final response = await postsService.getPost('1');
// 关闭ChopperClient的HTTP客户端。
// 调用close很重要,以释放资源并避免潜在的内存泄漏。
chopper.httpClient.close();
// 打印响应体。
print(response.body);
}
@ChopperApi(baseUrl: 'https://jsonplaceholder.typicode.com/posts')
abstract class PostsService extends ChopperService {
// 工厂方法用于创建PostsService的实例。
static PostsService create([ChopperClient? client]) => _$PostsService(client);
// 定义一个GET请求以通过ID获取帖子。
@Get(path: '/{id}')
Future<Response> getPost(@Path() String id);
}
使用Dio
要使用http_intercept
与Dio,你需要使用dio_compatibility_layer
包。此包提供了兼容层,使Dio能够与http_intercept
一起工作。以下是一个示例:
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:dio_compatibility_layer/dio_compatibility_layer.dart';
import 'package:http_intercept/http_intercept.dart';
Future<void> main() async {
// 创建一个带有拦截器的HttpClientProxy实例。
final httpClient = HttpClientProxy(
interceptors: [
HttpInterceptorWrapper(
onRequest: (request) {
// 向请求添加自定义头部。
request.headers['customHeader'] = 'customHeaderValue';
return OnRequest.next(request);
},
),
],
);
// 使用HttpClientProxy创建一个ConversionLayerAdapter。
// 此适配器允许Dio使用来自`http`包的HTTP客户端而不是其默认的HTTP客户端。
final dioAdapter = ConversionLayerAdapter(httpClient);
// 实例化Dio并配置其使用自定义HTTP客户端适配器。
final dio = Dio()..httpClientAdapter = dioAdapter;
// 发送GET请求。
final response = await dio.get(
'https://jsonplaceholder.typicode.com/posts/1',
);
// 关闭Dio实例。
// 调用close很重要,以释放资源并避免潜在的内存泄漏。
dio.close();
// 打印响应。
print(response);
}
使用Retrofit
使用http_intercept
与Retrofit的用法与Dio非常相似,因为两者都需要dio_compatibility_layer
包。以下是一个示例:
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:dio_compatibility_layer/dio_compatibility_layer.dart';
import 'package:http_intercept/http_intercept.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:retrofit/http.dart';
import 'package:retrofit/retrofit.dart';
part 'main_retrofit.g.dart';
Future<void> main() async {
// 创建一个带有拦截器的HttpClientProxy实例。
final httpClient = HttpClientProxy(
interceptors: [
HttpInterceptorWrapper(
onRequest: (request) {
// 向请求添加自定义头部。
request.headers['customHeader'] = 'customHeaderValue';
return OnRequest.next(request);
},
),
],
);
// 使用HttpClientProxy创建一个ConversionLayerAdapter。
// 此适配器允许Dio使用来自`http`包的HTTP客户端而不是其默认的HTTP客户端。
final dioAdapter = ConversionLayerAdapter(httpClient);
// 实例化Dio并配置其使用自定义HTTP客户端适配器。
final dio = Dio()..httpClientAdapter = dioAdapter;
// 使用配置好的Dio实例实例化一个Retrofit客户端。
final client = RestClient(dio);
// 发送GET请求以获取ID为'1'的帖子。
final response = await client.getPost('1');
// 关闭Dio实例。
// 调用close很重要,以释放资源并避免潜在的内存泄漏。
dio.close();
// 打印响应。
print(response);
}
@RestApi(baseUrl: 'https://jsonplaceholder.typicode.com/')
abstract class RestClient {
// 工厂构造函数用于使用Dio.f创建Retrofit客户端实例。
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;
// 定义一个GET请求以通过ID获取帖子。
@GET('/posts/{id}')
Future<Post> getPost(@Path('id') String id);
}
@JsonSerializable()
class Post {
const Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
final int userId;
final int id;
final String title;
final String body;
[@override](/user/override)
String toString() => 'Post id: $id - title: $title';
}
与http兼容的客户端(如cupertino_http
、cronet_http
和retry
)结合使用
这些示例演示了如何使用http_intercept
与cupertino_http
、cronet_http
和retry
等http兼容的客户端。需要注意的是,cupertino_http
和cronet_http
是专门为Flutter应用程序设计的,因此不能在纯Dart项目中使用。然而,在不同的客户端库中,集成原则是相似的,这允许你在每个客户端的独特功能上利用拦截器功能。
import 'dart:io';
import 'package:cronet_http/cronet_http.dart';
import 'package:cupertino_http/cupertino_http.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'package:http_intercept/http_intercept.dart';
void main() {
http.runWithClient(
() {
// 确保Flutter框架正确初始化。
WidgetsFlutterBinding.ensureInitialized();
// 运行Flutter应用。
runApp(const MyApp());
},
// 创建并配置带有拦截器的HTTP客户端。
_createHttpClient,
);
}
/// 应用程序的根小部件。
///
/// 此小部件设置了应用的基本结构,包括带有AppBar的主页和通过HTTP加载的居中图像。
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
// Flutter UI代码放在这里
}
}
/// 创建并配置带有拦截器的HTTP客户端。
///
/// 此函数根据平台设置一个基于客户端的拦截器。
http.Client _createHttpClient() => HttpClientProxy(
// 使用RetryClient作为内部客户端进行自动重试
innerClient: RetryClient(
// 根据平台选择适当的客户端
switch (Platform.operatingSystem) {
'android' => CronetClient.fromCronetEngine(CronetEngine.build()),
'ios' || 'macos' => CupertinoClient.defaultSessionConfiguration(),
_ => throw UnimplementedError(),
},
),
// 添加拦截器以修改请求
interceptors: [
HttpInterceptorWrapper(
onRequest: (requestOptions) {
// 添加自定义头部或修改请求
requestOptions.headers['Authorization'] = 'Bearer YOUR_TOKEN';
return OnRequest.next(requestOptions);
},
),
],
);
更多关于Flutter网络请求拦截插件http_intercept的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求拦截插件http_intercept的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,http_intercept
是一个强大的插件,它允许你拦截和修改 HTTP 请求与响应。这对于调试、日志记录、添加认证令牌等场景非常有用。以下是一个简单的示例,展示如何在 Flutter 项目中使用 http_intercept
插件。
步骤 1: 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 http_intercept
依赖:
dependencies:
flutter:
sdk: flutter
http_intercept: ^1.0.0 # 请检查最新版本号
然后运行 flutter pub get
来获取依赖。
步骤 2: 配置拦截器
接下来,在你的 Flutter 应用的入口文件(通常是 main.dart
)中配置拦截器。
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:http_intercept/http_intercept.dart';
void main() {
// 创建 Dio 实例
final dio = Dio();
// 创建拦截器管理器
final HttpInterceptManager interceptManager = HttpInterceptManager(dio);
// 添加请求拦截器
interceptManager.addRequestInterceptor((RequestOptions options) async {
// 在这里你可以修改请求选项,比如添加认证令牌
options.headers['Authorization'] = 'Bearer YOUR_ACCESS_TOKEN';
// 也可以打印请求信息用于调试
print('Request URL: ${options.path}');
print('Request Method: ${options.method}');
return options; // 不要忘记返回修改后的选项
});
// 添加响应拦截器
interceptManager.addResponseInterceptor((Response response, RequestOptions options) async {
// 在这里你可以修改响应数据,或者处理错误
// 打印响应信息用于调试
print('Response Status: ${response.statusCode}');
print('Response Data: ${response.data}');
return response; // 不要忘记返回响应
});
// 配置拦截器管理器
HttpOverrides.global = interceptManager.build();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Http Intercept Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 发起一个示例请求
dio.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => print('Final Response: ${response.data}'))
.catchErr(error => print('Error: ${error.response?.data ?? error.message}'));
},
child: Text('Fetch Data'),
),
),
),
);
}
}
解释
- 创建 Dio 实例:
Dio
是一个强大的 HTTP 客户端库,http_intercept
插件基于它进行拦截。 - 创建拦截器管理器:
HttpInterceptManager
用于管理请求和响应的拦截器。 - 添加请求拦截器:在请求发出前,你可以修改请求选项,比如添加认证令牌,或者打印请求信息。
- 添加响应拦截器:在响应到达后,你可以修改响应数据,或者处理错误,或者打印响应信息。
- 配置全局拦截器:通过
HttpOverrides.global
设置全局的拦截器管理器。 - 发起请求:在按钮点击事件中,使用配置好的
dio
实例发起 HTTP 请求。
这个示例展示了如何使用 http_intercept
插件来拦截和修改 HTTP 请求与响应。你可以根据实际需求进一步扩展和修改这个示例。