Ответ
Interceptor — это паттерн, позволяющий перехватывать и модифицировать HTTP-запросы и ответы на клиентской стороне. В Flutter он часто реализуется в HTTP-клиентах, таких как Dio или http, и действует как цепочка middleware.
Основные сценарии использования:
- Добавление общих заголовков: Автоматическое подставление токена авторизации.
- Логирование: Запись деталей запросов и ответов для отладки.
- Обработка ошибок: Глобальный перехват ошибок (например, 401 Unauthorized) для обновления токена и повторения запроса.
- Кеширование: Возврат закешированного ответа при определенных условиях.
Практический пример с Dio:
import 'package:dio/dio.dart';
final dio = Dio();
// Добавляем перехватчик для логирования и авторизации
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
// Логируем запрос
print('[${options.method}] ${options.uri}');
// Добавляем Bearer Token из локального хранилища
final token = await SecureStorage().getToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
return handler.next(options); // Продолжаем выполнение
},
onResponse: (Response response, ResponseInterceptorHandler handler) {
print('Response Status: ${response.statusCode}');
return handler.next(response);
},
onError: (DioException error, ErrorInterceptorHandler handler) async {
print('Error: ${error.message}');
// Пример: повтор запроса при 401 ошибке
if (error.response?.statusCode == 401) {
try {
// Пытаемся обновить токен
final newToken = await AuthService().refreshToken();
// Обновляем заголовок в исходном запросе
error.requestOptions.headers['Authorization'] = 'Bearer $newToken';
// Повторяем оригинальный запрос
final response = await dio.fetch(error.requestOptions);
return handler.resolve(response);
} catch (e) {
return handler.next(error); // Пробрасываем ошибку дальше
}
}
return handler.next(error);
},
),
);
Можно добавлять несколько интерцепторов, и они будут выполняться в порядке добавления.