Flutter网络请求拦截插件http_interceptor的使用
Flutter网络请求拦截插件http_interceptor的使用
简介
http_interceptor
是一个允许您拦截和修改来自Dart http
包的不同请求和响应的插件。您可以使用它来添加头信息、修改查询参数或记录响应日志。
安装
在您的pubspec.yaml
文件中添加http_interceptor
依赖:
dependencies:
http_interceptor: ^2.0.1 # 请确保使用最新版本
然后运行flutter pub get
以安装该包。
特性
- 🚦 拦截并更改未流式传输的请求和响应。
- ✨ 在发生错误或响应不符合预期时重试请求(处理自定义错误响应非常有用)。
- 👓 支持分离
GET
请求的参数。 - ⚡️ 标准
bodyBytes
用于ResponseData
,可以按所需格式进行编码或解码。 - 👌🏼 支持数组参数。
- 🖊 支持自签名证书(除Flutter Web外)。
- 🍦 兼容纯Dart项目或Flutter项目。
- 🎉 Null安全。
- ⏲ 配置超时时间与超时函数。
- ⏳ 配置每次重试尝试的延迟。
使用方法
构建自己的拦截器
要实现http_interceptor
,您需要实现InterceptorContract
抽象类并创建自己的拦截器。此抽象类有两个方法:interceptRequest
和interceptResponse
。
示例:日志拦截器
class LoggerInterceptor extends InterceptorContract {
@override
Future<BaseRequest> interceptRequest({required BaseRequest request}) async {
print('----- Request -----');
print(request.toString());
print(request.headers.toString());
return request;
}
@override
Future<BaseResponse> interceptResponse({required BaseResponse response}) async {
log('----- Response -----');
log('Code: ${response.statusCode}');
if (response is Response) {
log((response).body);
}
return response;
}
}
示例:更改头信息的拦截器
class WeatherApiInterceptor implements InterceptorContract {
@override
Future<BaseRequest> interceptRequest({required BaseRequest request}) async {
try {
request.url.queryParameters['appid'] = OPEN_WEATHER_API_KEY;
request.url.queryParameters['units'] = 'metric';
request.headers[HttpHeaders.contentTypeHeader] = "application/json";
} catch (e) {
print(e);
}
return request;
}
@override
Future<BaseResponse> interceptResponse({required BaseResponse response}) async => response;
}
示例:特定类型请求和响应的拦截器
class MultipartRequestInterceptor implements InterceptorContract {
@override
Future<BaseRequest> interceptRequest({required BaseRequest request}) async {
if (request is MultipartRequest) {
request.fields['app_version'] = await PackageInfo.fromPlatform().version;
}
return request;
}
@override
Future<BaseResponse> interceptResponse({required BaseResponse response}) async {
if (response is StreamedResponse) {
response.stream.asBroadcastStream().listen((data) {
print(data);
});
}
return response;
}
}
使用拦截器
使用InterceptedClient
通常,这种方法被采用是因为其易于测试和模拟。
class WeatherRepository {
Client client = InterceptedClient.build(interceptors: [
WeatherApiInterceptor(),
]);
Future<Map<String, dynamic>> fetchCityWeather(int id) async {
var parsedWeather;
try {
final response =
await client.get("$baseUrl/weather".toUri(), params: {'id': "$id"});
if (response.statusCode == 200) {
parsedWeather = json.decode(response.body);
} else {
throw Exception("Error while fetching. \n ${response.body}");
}
} catch (e) {
print(e);
}
return parsedWeather;
}
}
使用InterceptedHttp
对于只需要一次调用且需要拦截的情况,这是最直接的方法。
class WeatherRepository {
Future<Map<String, dynamic>> fetchCityWeather(int id) async {
var parsedWeather;
try {
final http = InterceptedHttp.build(interceptors: [
WeatherApiInterceptor(),
]);
final response =
await http.get("$baseUrl/weather".toUri(), params: {'id': "$id"});
if (response.statusCode == 200) {
parsedWeather = json.decode(response.body);
} else {
return Future.error(
"Error while fetching.",
StackTrace.fromString("${response.body}"),
);
}
} on SocketException {
return Future.error('No Internet connection 😑');
} on FormatException {
return Future.error('Bad response format 👎');
} on Exception {
return Future.error('Unexpected error 😢');
}
return parsedWeather;
}
}
请求重试
有时需要重试请求,例如由于令牌过期。以下是使用http_interceptor
实现过期令牌重试策略的示例。
class ExpiredTokenRetryPolicy extends RetryPolicy {
@override
Future<bool> shouldAttemptRetryOnResponse(BaseResponse response) async {
if (response.statusCode == 401) {
// Perform your token refresh here.
return true;
}
return false;
}
@override
Duration delayRetryAttemptOnResponse({required int retryAttempt}) {
return const Duration(milliseconds: 250) * math.pow(2.0, retryAttempt);
}
}
使用自签名证书
通过提供client
参数给InterceptedHttp
或InterceptedClient
,可以在构建时支持自签名证书。
Client client = InterceptedClient.build(
interceptors: [
WeatherApiInterceptor(),
],
client: IOClient(
HttpClient()
..badCertificateCallback = badCertificateCallback
..findProxy = findProxy,
),
);
示例应用
以下是一个简单的Flutter应用示例,展示了如何使用http_interceptor
。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_interceptor/http_interceptor.dart';
void main() => runApp(const ExamplesApp());
class ExamplesApp extends StatelessWidget {
const ExamplesApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: ExamplesMenuScreen(),
);
}
}
class ExamplesMenuScreen extends StatelessWidget {
const ExamplesMenuScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Examples'),
),
body: ListView(
shrinkWrap: true,
children: [
ListTile(
leading: const Icon(Icons.cloud),
title: const Text('Weather Example'),
subtitle: const Text('Simple HTTP Intercepting'),
onTap: () => Navigator.push<void>(context, WeatherApp.route()),
),
ListTile(
leading: const Icon(Icons.photo),
title: const Text('Remove Img Background Example'),
subtitle: const Text('Multipart Intercepting'),
onTap: () => Navigator.push<void>(context, MultipartApp.route()),
),
],
),
);
}
}
// 假设WeatherApp和MultipartApp是两个具体的页面
在这个例子中,我们创建了一个包含两个选项的应用程序,分别演示了简单的HTTP拦截和多部分拦截。每个选项点击后会导航到相应的页面。
希望这些内容能帮助您更好地理解和使用http_interceptor
插件!如果您有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter网络请求拦截插件http_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求拦截插件http_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用http_interceptor
插件来实现网络请求拦截的示例代码。http_interceptor
插件允许你在发送请求和接收响应时拦截它们,以便进行日志记录、身份验证或其他处理。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加http_interceptor
和dio
(一个流行的HTTP客户端库)的依赖:
dependencies:
flutter:
sdk: flutter
dio: ^4.0.0
http_interceptor: ^1.0.0
然后运行flutter pub get
来安装这些依赖。
2. 创建拦截器
接下来,创建一个自定义的拦截器类。例如,我们可以创建一个日志拦截器来记录发送的请求和接收的响应。
import 'package:dio/dio.dart';
import 'package:http_interceptor/http_interceptor.dart';
class LoggingInterceptor implements HttpInterceptor {
@override
Future<void> onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
print("Sending request to ${options.path}");
print("Request Headers: ${options.headers}");
handler.next(options);
}
@override
Future<void> onResponse(Response response, ResponseInterceptorHandler handler) async {
print("Received response from ${response.requestOptions.path}");
print("Response Status: ${response.statusCode}");
print("Response Data: ${response.data}");
handler.next(response);
}
@override
Future<void> onError(DioError err, ErrorInterceptorHandler handler) async {
print("Request failed: ${err.message}");
handler.next(err);
}
}
3. 配置Dio客户端
在你的应用程序中配置Dio
客户端并使用你创建的拦截器。
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:http_interceptor/http_interceptor.dart';
import 'logging_interceptor.dart'; // 假设你将上面的拦截器代码放在这个文件里
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final Dio _dio = Dio();
final HttpClientAdapter _httpClientAdapter = HttpClientAdapter(_dio);
@override
void initState() {
super.initState();
// 添加拦截器
_httpClientAdapter.addInterceptors([
LoggingInterceptor(),
]);
// 示例网络请求
_makeRequest();
}
void _makeRequest() async {
try {
Response response = await _dio.get("https://jsonplaceholder.typicode.com/posts/1");
print("Response Data: ${response.data}");
} catch (error) {
print("Error: ${error}");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Http Interceptor Example"),
),
body: Center(
child: Text("Check the console for logging output."),
),
);
}
}
4. 运行应用程序
现在,运行你的Flutter应用程序。你应该会在控制台中看到拦截器记录的请求和响应日志。
这个示例展示了如何使用http_interceptor
插件来拦截和记录HTTP请求和响应。你可以根据需要扩展拦截器的功能,例如添加身份验证令牌、处理错误等。