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.

112 lines
2.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> getJson(Uri uri, {Map<String, dynamic>? search}) async {
var resText = await get(uri, search: search);
var resData = jsonDecode(resText);
if (resData is Map) {
return resData;
} else {
return {};
}
}
}