You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.8 KiB
Dart
150 lines
3.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
|
|
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
|
import 'package:dio_http2_adapter/dio_http2_adapter.dart';
|
|
import 'package:cookie_jar/cookie_jar.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:isekai_wiki/global.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
class HttpResponseException implements Exception {
|
|
int statusCode;
|
|
String? statusText;
|
|
|
|
HttpResponseException(this.statusCode, {this.statusText});
|
|
|
|
@override
|
|
String toString() {
|
|
return "Http error: $statusCode $statusText";
|
|
}
|
|
}
|
|
|
|
class BaseApi {
|
|
static Dio? _dioInstance;
|
|
static CookieJar? cookieJar;
|
|
|
|
static Future<Dio> createClient() async {
|
|
var dio = Dio();
|
|
|
|
if (!kIsWeb) {
|
|
// HTTP2
|
|
/*
|
|
dio.httpClientAdapter = Http2Adapter(
|
|
ConnectionManager(
|
|
idleTimeout: 10000,
|
|
),
|
|
);
|
|
*/
|
|
|
|
// Cookie
|
|
var tempDir = await getTemporaryDirectory();
|
|
|
|
cookieJar = PersistCookieJar(
|
|
storage: FileStorage("${tempDir.path}/cookies"),
|
|
);
|
|
dio.interceptors.add(CookieManager(cookieJar!));
|
|
|
|
// 缓存
|
|
final cacheOptions = CacheOptions(
|
|
store: MemCacheStore(),
|
|
policy: CachePolicy.request,
|
|
maxStale: const Duration(days: 7),
|
|
priority: CachePriority.normal,
|
|
cipher: null,
|
|
keyBuilder: CacheOptions.defaultCacheKeyBuilder,
|
|
allowPostMethod: false,
|
|
);
|
|
dio.interceptors.add(DioCacheInterceptor(options: cacheOptions));
|
|
|
|
// 自定义Header
|
|
dio.interceptors.add(
|
|
InterceptorsWrapper(onRequest: (options, handler) {
|
|
options.headers["X-IsekaiWikiApp-Version"] =
|
|
Global.packageInfo?.version ?? "unknow";
|
|
options.headers["User-Agent"] = "";
|
|
return handler.next(options);
|
|
}),
|
|
);
|
|
}
|
|
|
|
return dio;
|
|
}
|
|
|
|
static Future<Dio> getClient() async {
|
|
_dioInstance ??= await createClient();
|
|
|
|
return _dioInstance!;
|
|
}
|
|
|
|
static Future<void> clearCookie() async {
|
|
await cookieJar?.deleteAll();
|
|
}
|
|
|
|
static Future<String> get(Uri uri, {Map<String, dynamic>? search}) async {
|
|
var client = await getClient();
|
|
var res = await client.get<String>(
|
|
uri.toString(),
|
|
queryParameters: search,
|
|
options: Options(responseType: ResponseType.plain),
|
|
);
|
|
|
|
if (res.statusCode != null && res.statusCode != 200) {
|
|
throw HttpResponseException(res.statusCode!,
|
|
statusText: res.statusMessage!);
|
|
}
|
|
|
|
return res.data ?? "";
|
|
}
|
|
|
|
static Future<Map<String, dynamic>> getJson(Uri uri,
|
|
{Map<String, dynamic>? search}) async {
|
|
var resText = await get(uri, search: search);
|
|
var resData = jsonDecode(resText);
|
|
|
|
if (resData is Map<String, dynamic>) {
|
|
return resData;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
static Future<String> post(Uri uri,
|
|
{Map<String, dynamic>? search, dynamic data}) async {
|
|
var client = await getClient();
|
|
|
|
String? contentType;
|
|
if (data is Map) {
|
|
contentType = Headers.formUrlEncodedContentType;
|
|
}
|
|
|
|
var res = await client.post<String>(
|
|
uri.toString(),
|
|
queryParameters: search,
|
|
data: data,
|
|
options:
|
|
Options(responseType: ResponseType.plain, contentType: contentType),
|
|
);
|
|
|
|
if (res.statusCode != null && res.statusCode != 200) {
|
|
throw HttpResponseException(res.statusCode!,
|
|
statusText: res.statusMessage!);
|
|
}
|
|
|
|
return res.data ?? "";
|
|
}
|
|
|
|
static Future<Map> postJson(Uri uri,
|
|
{Map<String, dynamic>? search, dynamic data}) async {
|
|
var resText = await post(uri, search: search, data: data);
|
|
var resData = jsonDecode(resText);
|
|
|
|
if (resData is Map) {
|
|
return resData;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
}
|