Files
AutoJudge-Flutter/lib/services/http_client.dart
2025-11-13 09:14:49 +08:00

144 lines
3.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}