http 初始化
This commit is contained in:
7
lib/http/api.dart
Normal file
7
lib/http/api.dart
Normal file
@ -0,0 +1,7 @@
|
||||
class Api {
|
||||
// 推荐视频
|
||||
static const String recommendList = '/x/web-interface/index/top/feed/rcmd';
|
||||
// 视频详情
|
||||
// 竖屏 https://api.bilibili.com/x/web-interface/view?aid=527403921
|
||||
static const String videoDetail = '/x/web-interface/view';
|
||||
}
|
4
lib/http/constants.dart
Normal file
4
lib/http/constants.dart
Normal file
@ -0,0 +1,4 @@
|
||||
class HttpString {
|
||||
static const String baseUrl = 'https://www.bilibili.com';
|
||||
static const String baseApiUrl = 'https://api.bilibili.com';
|
||||
}
|
181
lib/http/init.dart
Normal file
181
lib/http/init.dart
Normal file
@ -0,0 +1,181 @@
|
||||
// ignore_for_file: avoid_print
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'package:pilipala/utils/utils.dart';
|
||||
import 'package:pilipala/http/constants.dart';
|
||||
import 'package:pilipala/http/interceptor.dart';
|
||||
import 'package:dio_http2_adapter/dio_http2_adapter.dart';
|
||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||
|
||||
class Request {
|
||||
static final Request _instance = Request._internal();
|
||||
|
||||
factory Request() => _instance;
|
||||
|
||||
static Dio dio = Dio()
|
||||
..httpClientAdapter = Http2Adapter(
|
||||
ConnectionManager(
|
||||
idleTimeout: const Duration(milliseconds: 10000),
|
||||
// Ignore bad certificate
|
||||
onClientCreate: (_, config) => config.onBadCertificate = (_) => true,
|
||||
),
|
||||
);
|
||||
|
||||
/// 设置cookie
|
||||
static setCookie() async {
|
||||
var cookiePath = await Utils.getCookiePath();
|
||||
var cookieJar = PersistCookieJar(
|
||||
ignoreExpires: true,
|
||||
storage: FileStorage(cookiePath),
|
||||
);
|
||||
|
||||
dio.interceptors.add(CookieManager(cookieJar));
|
||||
|
||||
var cookie = await CookieManager(cookieJar)
|
||||
.cookieJar
|
||||
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
||||
if (cookie.isEmpty) {
|
||||
try {
|
||||
await Request().get(HttpString.baseUrl);
|
||||
} catch (e) {
|
||||
log("setCookie, ${e.toString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* config it and create
|
||||
*/
|
||||
Request._internal() {
|
||||
//BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
|
||||
BaseOptions options = BaseOptions(
|
||||
//请求基地址,可以包含子路径
|
||||
baseUrl: HttpString.baseApiUrl,
|
||||
//连接服务器超时时间,单位是毫秒.
|
||||
connectTimeout: const Duration(milliseconds: 12000),
|
||||
//响应流上前后两次接受到数据的间隔,单位为毫秒。
|
||||
receiveTimeout: const Duration(milliseconds: 12000),
|
||||
//Http请求头.
|
||||
// headers: {
|
||||
// 'cookie': '',
|
||||
// },
|
||||
);
|
||||
|
||||
dio.options = options;
|
||||
|
||||
//添加拦截器
|
||||
dio.interceptors
|
||||
..add(ApiInterceptor())
|
||||
// 日志拦截器 输出请求、响应内容
|
||||
..add(LogInterceptor(
|
||||
request: false,
|
||||
requestHeader: false,
|
||||
responseHeader: false,
|
||||
));
|
||||
dio.transformer = BackgroundTransformer();
|
||||
dio.options.validateStatus = (status) {
|
||||
return status! >= 200 && status < 300 || status == 304 || status == 302;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* get请求
|
||||
*/
|
||||
get(url, {data, cacheOptions, options, cancelToken, extra}) async {
|
||||
Response response;
|
||||
Options options;
|
||||
String ua = 'pc';
|
||||
ResponseType resType = ResponseType.json;
|
||||
if (extra != null) {
|
||||
ua = extra!['ua'] ?? 'pc';
|
||||
resType = extra!['resType'] ?? ResponseType.json;
|
||||
}
|
||||
if (cacheOptions != null) {
|
||||
cacheOptions.headers = {'user-agent': headerUa(ua)};
|
||||
options = cacheOptions;
|
||||
} else {
|
||||
options = Options();
|
||||
options.headers = {'user-agent': headerUa(ua)};
|
||||
options.responseType = resType;
|
||||
}
|
||||
try {
|
||||
response = await dio.get(
|
||||
url,
|
||||
queryParameters: data,
|
||||
options: options,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
return response;
|
||||
} on DioError catch (e) {
|
||||
print('get error: $e');
|
||||
return Future.error(ApiInterceptor.dioError(e));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* post请求
|
||||
*/
|
||||
post(url, {data, options, cancelToken, extra}) async {
|
||||
print('post-data: $data');
|
||||
Response response;
|
||||
try {
|
||||
response = await dio.post(
|
||||
url,
|
||||
data: data,
|
||||
options: options,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
print('post success: ${response.data}');
|
||||
return response;
|
||||
} on DioError catch (e) {
|
||||
print('post error: $e');
|
||||
return Future.error(ApiInterceptor.dioError(e));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 下载文件
|
||||
*/
|
||||
downloadFile(urlPath, savePath) async {
|
||||
Response response;
|
||||
try {
|
||||
response = await dio.download(urlPath, savePath,
|
||||
onReceiveProgress: (int count, int total) {
|
||||
//进度
|
||||
// print("$count $total");
|
||||
});
|
||||
print('downloadFile success: ${response.data}');
|
||||
|
||||
return response.data;
|
||||
} on DioError catch (e) {
|
||||
print('downloadFile error: $e');
|
||||
return Future.error(ApiInterceptor.dioError(e));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 取消请求
|
||||
*
|
||||
* 同一个cancel token 可以用于多个请求,当一个cancel token取消时,所有使用该cancel token的请求都会被取消。
|
||||
* 所以参数可选
|
||||
*/
|
||||
void cancelRequests(CancelToken token) {
|
||||
token.cancel("cancelled");
|
||||
}
|
||||
|
||||
String headerUa(ua) {
|
||||
String headerUa = '';
|
||||
if (ua == 'mob') {
|
||||
headerUa = Platform.isIOS
|
||||
? 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1'
|
||||
: 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36';
|
||||
} else {
|
||||
headerUa =
|
||||
'Mozilla/5.0 (MaciMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36';
|
||||
}
|
||||
return headerUa;
|
||||
}
|
||||
}
|
71
lib/http/interceptor.dart
Normal file
71
lib/http/interceptor.dart
Normal file
@ -0,0 +1,71 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
class ApiInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
// print("请求之前");
|
||||
// 在请求之前添加头部或认证信息
|
||||
// options.headers['Authorization'] = 'Bearer token';
|
||||
// options.headers['Content-Type'] = 'application/json';
|
||||
handler.next(options);
|
||||
}
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
// print("响应之前");
|
||||
handler.next(response);
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(DioError err, ErrorInterceptorHandler handler) {
|
||||
// 处理网络请求错误
|
||||
|
||||
handler.next(err);
|
||||
super.onError(err, handler);
|
||||
}
|
||||
|
||||
static Future dioError(DioError error) async {
|
||||
switch (error.type) {
|
||||
case DioErrorType.badCertificate:
|
||||
return '证书有误!';
|
||||
case DioErrorType.badResponse:
|
||||
return '服务器异常,请稍后重试!';
|
||||
case DioErrorType.cancel:
|
||||
return "请求已被取消,请重新请求";
|
||||
case DioErrorType.connectionError:
|
||||
return '连接错误,请检查网络设置';
|
||||
case DioErrorType.connectionTimeout:
|
||||
return "网络连接超时,请检查网络设置";
|
||||
case DioErrorType.receiveTimeout:
|
||||
return "响应超时,请稍后重试!";
|
||||
case DioErrorType.sendTimeout:
|
||||
return "发送请求超时,请检查网络设置";
|
||||
case DioErrorType.unknown:
|
||||
var res = await checkConect();
|
||||
return "$res 网络异常,请稍后重试!";
|
||||
default:
|
||||
return "Dio异常";
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> checkConect() async {
|
||||
final connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.mobile) {
|
||||
return 'connected with mobile network';
|
||||
} else if (connectivityResult == ConnectivityResult.wifi) {
|
||||
return 'connected with wifi network';
|
||||
} else if (connectivityResult == ConnectivityResult.ethernet) {
|
||||
// I am connected to a ethernet network.
|
||||
} else if (connectivityResult == ConnectivityResult.vpn) {
|
||||
// I am connected to a vpn network.
|
||||
// Note for iOS and macOS:
|
||||
// There is no separate network interface type for [vpn].
|
||||
// It returns [other] on any device (also simulator)
|
||||
} else if (connectivityResult == ConnectivityResult.other) {
|
||||
// I am connected to a network which is not in the above mentioned networks.
|
||||
} else if (connectivityResult == ConnectivityResult.none) {
|
||||
return 'not connected to any network';
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:pilipala/http/init.dart';
|
||||
import 'package:pilipala/router/app_pages.dart';
|
||||
import 'package:pilipala/pages/main/view.dart';
|
||||
|
||||
void main() {
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await Request.setCookie();
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
|
16
lib/utils/utils.dart
Normal file
16
lib/utils/utils.dart
Normal file
@ -0,0 +1,16 @@
|
||||
// 工具函数
|
||||
import 'dart:io';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class Utils {
|
||||
static Future<String> getCookiePath() async {
|
||||
Directory tempDir = await getApplicationSupportDirectory();
|
||||
String tempPath = "${tempDir.path}/.plpl/";
|
||||
Directory dir = Directory(tempPath);
|
||||
bool b = await dir.exists();
|
||||
if (!b) {
|
||||
dir.createSync(recursive: true);
|
||||
}
|
||||
return tempPath;
|
||||
}
|
||||
}
|
@ -5,11 +5,13 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import connectivity_plus
|
||||
import dynamic_color
|
||||
import path_provider_foundation
|
||||
import sqflite
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
|
93
pubspec.lock
93
pubspec.lock
@ -1,6 +1,14 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -65,6 +73,30 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
connectivity_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
sha256: d73575bb66216738db892f72ba67dc478bd3b5490fbbcf43644b57645eabc822
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.4"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: connectivity_plus_platform_interface
|
||||
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.4"
|
||||
cookie_jar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cookie_jar
|
||||
sha256: d1cc6516a190ba667941f722b6365d202caff3dacb38de24268b8d6ff1ec8a1d
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -81,6 +113,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -89,6 +129,22 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
dio_cookie_manager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dio_cookie_manager
|
||||
sha256: b45f11c2fcbccf39c5952ab68910b3a155486c4fa730ceb4ce867c4943169ea1
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
dio_http2_adapter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dio_http2_adapter
|
||||
sha256: b06a02faaff972c4809c4ada7a2f71f6c74ce21f0feee79b357f2a9590c049d4
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
dynamic_color:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -155,6 +211,11 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
get:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -171,6 +232,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
http2:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http2
|
||||
sha256: "58805ebc6513eed3b98ee0a455a8357e61d187bf2e0fdc1e53120770f78de258"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -219,6 +288,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
nm:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nm
|
||||
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
octo_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -291,6 +368,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -440,6 +525,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.2.2"
|
||||
sdks:
|
||||
dart: ">=2.19.6 <3.0.0"
|
||||
flutter: ">=3.4.0-17.0.pre"
|
||||
|
@ -41,6 +41,10 @@ dependencies:
|
||||
|
||||
# 网络
|
||||
dio: ^5.1.1
|
||||
cookie_jar: ^3.0.0
|
||||
dio_http2_adapter: ^2.2.0
|
||||
dio_cookie_manager: ^2.1.4
|
||||
connectivity_plus: ^3.0.4
|
||||
|
||||
# 图片
|
||||
cached_network_image: ^3.2.3
|
||||
|
@ -6,9 +6,12 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <dynamic_color/dynamic_color_plugin_c_api.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
DynamicColorPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
connectivity_plus
|
||||
dynamic_color
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user