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 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 getClient() async { _dioInstance ??= await createClient(); return _dioInstance!; } static Future clearCookie() async { await cookieJar?.deleteAll(); } static Future get(Uri uri, {Map? search}) async { var client = await getClient(); var res = await client.get( 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 getJson(Uri uri, {Map? search}) async { var resText = await get(uri, search: search); var resData = jsonDecode(resText); if (resData is Map) { return resData; } else { return {}; } } }