144 lines
3.9 KiB
Dart
144 lines
3.9 KiB
Dart
|
|
import 'package:dio/dio.dart';
|
|||
|
|
|
|||
|
|
/// HTTP客户端封装类,提供统一的网络请求接口
|
|||
|
|
class HTTPClient {
|
|||
|
|
late Dio _dio;
|
|||
|
|
final Map<String, String> _cookies = {};
|
|||
|
|
|
|||
|
|
HTTPClient({String? baseUrl, int timeout = 30000}) {
|
|||
|
|
_dio = Dio(
|
|||
|
|
BaseOptions(
|
|||
|
|
baseUrl: baseUrl ?? '',
|
|||
|
|
connectTimeout: Duration(milliseconds: timeout),
|
|||
|
|
receiveTimeout: Duration(milliseconds: timeout),
|
|||
|
|
sendTimeout: Duration(milliseconds: timeout),
|
|||
|
|
headers: {
|
|||
|
|
'User-Agent':
|
|||
|
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
|||
|
|
},
|
|||
|
|
validateStatus: (status) => status != null && status < 500,
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 添加拦截器用于Cookie管理和日志
|
|||
|
|
_dio.interceptors.add(
|
|||
|
|
InterceptorsWrapper(
|
|||
|
|
onRequest: (options, handler) {
|
|||
|
|
// 添加Cookie到请求头
|
|||
|
|
if (_cookies.isNotEmpty) {
|
|||
|
|
final cookieStr = _cookies.entries
|
|||
|
|
.map((e) => '${e.key}=${e.value}')
|
|||
|
|
.join('; ');
|
|||
|
|
options.headers['Cookie'] = cookieStr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 打印请求信息
|
|||
|
|
print('🌐 ${options.method} ${options.uri}');
|
|||
|
|
|
|||
|
|
return handler.next(options);
|
|||
|
|
},
|
|||
|
|
onResponse: (response, handler) {
|
|||
|
|
// 从响应中提取Cookie
|
|||
|
|
final setCookie = response.headers['set-cookie'];
|
|||
|
|
if (setCookie != null) {
|
|||
|
|
for (var cookie in setCookie) {
|
|||
|
|
_parseCookie(cookie);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
final statusCode = response.statusCode ?? 0;
|
|||
|
|
|
|||
|
|
// 如果状态码 >= 400,打印详细错误信息
|
|||
|
|
if (statusCode >= 400) {
|
|||
|
|
print(
|
|||
|
|
'❌ Response Error: $statusCode ${response.requestOptions.uri}',
|
|||
|
|
);
|
|||
|
|
print('❌ Response Headers: ${response.headers}');
|
|||
|
|
print('❌ Response Data: ${response.data}');
|
|||
|
|
} else {
|
|||
|
|
// 正常响应只打印状态码
|
|||
|
|
print('✅ $statusCode ${response.requestOptions.uri}');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return handler.next(response);
|
|||
|
|
},
|
|||
|
|
onError: (error, handler) {
|
|||
|
|
print('❌ HTTP Error: ${error.message}');
|
|||
|
|
print('❌ Error type: ${error.type}');
|
|||
|
|
print(
|
|||
|
|
'❌ Request: ${error.requestOptions.method} ${error.requestOptions.uri}',
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (error.response != null) {
|
|||
|
|
print('❌ Status code: ${error.response?.statusCode}');
|
|||
|
|
print('❌ Response Headers: ${error.response?.headers}');
|
|||
|
|
print('❌ Response Data: ${error.response?.data}');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return handler.next(error);
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 解析Cookie字符串并存储
|
|||
|
|
void _parseCookie(String cookieStr) {
|
|||
|
|
final parts = cookieStr.split(';')[0].split('=');
|
|||
|
|
if (parts.length == 2) {
|
|||
|
|
_cookies[parts[0].trim()] = parts[1].trim();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// GET请求
|
|||
|
|
Future<Response> get(
|
|||
|
|
String path, {
|
|||
|
|
Map<String, dynamic>? params,
|
|||
|
|
Options? options,
|
|||
|
|
}) async {
|
|||
|
|
return await _dio.get(path, queryParameters: params, options: options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// POST请求
|
|||
|
|
Future<Response> post(
|
|||
|
|
String path, {
|
|||
|
|
dynamic data,
|
|||
|
|
Map<String, dynamic>? queryParameters,
|
|||
|
|
Options? options,
|
|||
|
|
}) async {
|
|||
|
|
return await _dio.post(
|
|||
|
|
path,
|
|||
|
|
data: data,
|
|||
|
|
queryParameters: queryParameters,
|
|||
|
|
options: options,
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 设置Cookie
|
|||
|
|
void setCookie(String name, String value) {
|
|||
|
|
_cookies[name] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 获取Cookie
|
|||
|
|
String? getCookie(String name) {
|
|||
|
|
return _cookies[name];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 获取所有Cookie
|
|||
|
|
Map<String, String> getAllCookies() {
|
|||
|
|
return Map.from(_cookies);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 清除所有Cookie
|
|||
|
|
void clearCookies() {
|
|||
|
|
_cookies.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 关闭客户端
|
|||
|
|
void close() {
|
|||
|
|
_dio.close();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 获取Dio实例(用于高级操作)
|
|||
|
|
Dio get dio => _dio;
|
|||
|
|
}
|