在Flutter项目中使用网络请求的方式大致可分为两种,分别是Dart原生的网络请求 HttpClient类以及第三方开源的网络请求库。在Dart社区开源的第三方http请求库中Flutter 中文网 开源的 Dio库 人气最高。
下面我们先来比较下这两种网络请求方式,然后再看怎么基于 Dio库封装方便使用的网络请求工具类HttpManager。
Dart IO库中提供了用于发起Http请求的一些类,我们可以直接使用HttpClient来发起请求。使用HttpClient发起请求分为五步:
HttpClient httpClient = new HttpClient(); 复制代码
HttpClientRequest request = await httpClient.getUrl(uri); 复制代码
这一步可以使用任意Http Method,如httpClient.post(...)、httpClient.delete(...)等。如果包含Query参数,可以在构建uri时添加,如:
Uri uri=Uri(scheme: "https", host: "flutterchina.club", queryParameters: { "xx":"xx", "yy":"dd" }); 复制代码
通过HttpClientRequest可以设置请求header,如:
request.headers.add("user-agent", "test"); 复制代码
如果是post或put等可以携带请求体方法,可以通过HttpClientRequest对象发送request body,如:
String payload="..."; request.add(utf8.encode(payload)); //request.addStream(_inputStream); //可以直接添加输入流 复制代码
HttpClientResponse response = await request.close(); 复制代码
这一步完成后,请求信息就已经发送给服务器了,返回一个HttpClientResponse对象,它包含响应头(header)和响应流(响应体的Stream),接下来就可以通过读取响应流来获取响应内容。
String responseBody = await response.transform(utf8.decoder).join(); 复制代码
我们通过读取响应流来获取服务器返回的数据,在读取时我们可以设置编码格式,这里是utf8。
httpClient.close(); 复制代码
关闭client后,通过该client发起的所有请求都会中止。
以上的步骤是dart原生网络HttpClient使用方式,可以发现直接使用HttpClient发起网络请求是比较麻烦的,很多事情都得手动处理,如果再涉及到文件上传/下载、Cookie管理等就会变得非常繁琐,并且HttpClient本身功能较弱,很多常用功能都不支持。
dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等...
dependencies: dio: ^x.x.x #请使用pub上的最新版本 复制代码
import 'package:dio/dio.dart'; Dio dio = Dio(); 复制代码
接下来就可以通过 dio实例来发起网络请求了,注意,一个dio实例可以发起多个http请求,一般来说,APP只有一个http数据源时,dio应该使用单例模式。
Response response; response=await dio.get("/test?id=12&name=cheney") print(response.data.toString()); 复制代码
Response response; response=await dio.post("/test",data:{"id":12,"name":"cheney"}) print(response.data.toString()); 复制代码
以上就是Dio库网络请求的基本使用,是不是很简单,除了这些基本的用法,dio还支持请求配置、拦截器等,官方资料比较详细,故在这里不再赘述,详情可以参考dio主页: github.com/flutterchin… 。
做一些公共处理,方便灵活的使用。
类名 | 描述 |
---|---|
HttpManager | 网络请求管理类 |
HttpError | 网络请求统一错误类 |
LogInterceptor | 网络请求工具类 |
import 'dart:core'; import 'package:connectivity/connectivity.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_common_utils/http/http_error.dart'; import 'package:flutter_common_utils/log_util.dart'; ///http请求成功回调 typedef HttpSuccessCallback<T> = void Function(dynamic data); ///失败回调 typedef HttpFailureCallback = void Function(HttpError data); ///数据解析回调 typedef T JsonParse<T>(dynamic data); /// @desc 封装 http 请求 /// @time 2019/3/15 10:35 AM /// @author Cheney class HttpManager { ///同一个CancelToken可以用于多个请求,当一个CancelToken取消时,所有使用该CancelToken的请求都会被取消,一个页面对应一个CancelToken。 Map<String, CancelToken> _cancelTokens = Map<String, CancelToken>(); ///超时时间 static const int CONNECT_TIMEOUT = 30000; static const int RECEIVE_TIMEOUT = 30000; /// http request methods static const String GET = 'get'; static const String POST = 'post'; Dio _client; static final HttpManager _instance = HttpManager._internal(); factory HttpManager() => _instance; Dio get client => _client; /// 创建 dio 实例对象 HttpManager._internal() { if (_client == null) { /// 全局属性:请求前缀、连接超时时间、响应超时时间 BaseOptions options = BaseOptions( connectTimeout: CONNECT_TIMEOUT, receiveTimeout: RECEIVE_TIMEOUT, ); _client = Dio(options); } } ///初始化公共属性 /// /// [baseUrl] 地址前缀 /// [connectTimeout] 连接超时赶时间 /// [receiveTimeout] 接收超时赶时间 /// [interceptors] 基础拦截器 void init( {String baseUrl, int connectTimeout, int receiveTimeout, List<Interceptor> interceptors}) { _client.options = _client.options.merge( baseUrl: baseUrl, connectTimeout: connectTimeout, receiveTimeout: receiveTimeout, ); if (interceptors != null && interceptors.isNotEmpty) { _client.interceptors..addAll(interceptors); } } ///Get网络请求 /// ///[url] 网络请求地址不包含域名 ///[params] url请求参数支持restful ///[options] 请求配置 ///[successCallback] 请求成功回调 ///[errorCallback] 请求失败回调 ///[tag] 请求统一标识,用于取消网络请求 void get({ @required String url, Map<String, dynamic> params, Options options, HttpSuccessCallback successCallback, HttpFailureCallback errorCallback, @required String tag, }) async { _request( url: url, params: params, method: GET, successCallback: successCallback, errorCallback: errorCallback, tag: tag, ); } ///post网络请求 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[successCallback] 请求成功回调 ///[errorCallback] 请求失败回调 ///[tag] 请求统一标识,用于取消网络请求 void post({ @required String url, data, Map<String, dynamic> params, Options options, HttpSuccessCallback successCallback, HttpFailureCallback errorCallback, @required String tag, }) async { _request( url: url, data: data, method: POST, params: params, successCallback: successCallback, errorCallback: errorCallback, tag: tag, ); } ///统一网络请求 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[successCallback] 请求成功回调 ///[errorCallback] 请求失败回调 ///[tag] 请求统一标识,用于取消网络请求 void _request({ @required String url, String method, data, Map<String, dynamic> params, Options options, HttpSuccessCallback successCallback, HttpFailureCallback errorCallback, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { if (errorCallback != null) { errorCallback(HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } LogUtil.v("请求网络异常,请稍后重试!"); return; } //设置默认值 params = params ?? {}; method = method ?? 'GET'; options?.method = method; options = options ?? Options( method: method, ); url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } Response<Map<String, dynamic>> response = await _client.request(url, data: data, queryParameters: params, options: options, cancelToken: cancelToken); String statusCode = response.data["statusCode"]; if (statusCode == "0") { //成功 if (successCallback != null) { successCallback(response.data["data"]); } } else { //失败 String message = response.data["statusDesc"]; LogUtil.v("请求服务器出错:$message"); if (errorCallback != null) { errorCallback(HttpError(statusCode, message)); } } } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); if (errorCallback != null && e.type != DioErrorType.CANCEL) { errorCallback(HttpError.dioError(e)); } } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); if (errorCallback != null) { errorCallback(HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } } ///下载文件 /// ///[url] 下载地址 ///[savePath] 文件保存路径 ///[onReceiveProgress] 文件保存路径 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[successCallback] 请求成功回调 ///[errorCallback] 请求失败回调 ///[tag] 请求统一标识,用于取消网络请求 void download({ @required String url, @required savePath, ProgressCallback onReceiveProgress, Map<String, dynamic> params, data, Options options, HttpSuccessCallback successCallback, HttpFailureCallback errorCallback, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { if (errorCallback != null) { errorCallback(HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } LogUtil.v("请求网络异常,请稍后重试!"); return; } ////0代表不设置超时 int receiveTimeout = 0; options ??= options == null ? Options(receiveTimeout: receiveTimeout) : options.merge(receiveTimeout: receiveTimeout); //设置默认值 params = params ?? {}; url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } Response response = await _client.download(url, savePath, onReceiveProgress: onReceiveProgress, queryParameters: params, data: data, options: options, cancelToken: cancelToken); //成功 if (successCallback != null) { successCallback(response.data); } } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); if (errorCallback != null && e.type != DioErrorType.CANCEL) { errorCallback(HttpError.dioError(e)); } } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); if (errorCallback != null) { errorCallback(HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } } ///上传文件 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[onSendProgress] 上传进度 ///[params] url请求参数支持restful ///[options] 请求配置 ///[successCallback] 请求成功回调 ///[errorCallback] 请求失败回调 ///[tag] 请求统一标识,用于取消网络请求 void upload({ @required String url, FormData data, ProgressCallback onSendProgress, Map<String, dynamic> params, Options options, HttpSuccessCallback successCallback, HttpFailureCallback errorCallback, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { if (errorCallback != null) { errorCallback(HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } LogUtil.v("请求网络异常,请稍后重试!"); return; } //设置默认值 params = params ?? {}; //强制 POST 请求 options?.method = POST; options = options ?? Options( method: POST, ); url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } Response<Map<String, dynamic>> response = await _client.request(url, onSendProgress: onSendProgress, data: data, queryParameters: params, options: options, cancelToken: cancelToken); String statusCode = response.data["statusCode"]; if (statusCode == "0") { //成功 if (successCallback != null) { successCallback(response.data["data"]); } } else { //失败 String message = response.data["statusDesc"]; LogUtil.v("请求服务器出错:$message"); if (errorCallback != null) { errorCallback(HttpError(statusCode, message)); } } } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); if (errorCallback != null && e.type != DioErrorType.CANCEL) { errorCallback(HttpError.dioError(e)); } } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); if (errorCallback != null) { errorCallback(HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } } ///GET异步网络请求 /// ///[url] 网络请求地址不包含域名 ///[params] url请求参数支持restful ///[options] 请求配置 ///[tag] 请求统一标识,用于取消网络请求 Future<T> getAsync<T>({ @required String url, Map<String, dynamic> params, Options options, JsonParse<T> jsonParse, @required String tag, }) async { return _requestAsync( url: url, method: GET, params: params, options: options, jsonParse: jsonParse, tag: tag, ); } ///POST 异步网络请求 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[tag] 请求统一标识,用于取消网络请求 Future<T> postAsync<T>({ @required String url, data, Map<String, dynamic> params, Options options, JsonParse<T> jsonParse, @required String tag, }) async { return _requestAsync( url: url, method: POST, data: data, params: params, options: options, jsonParse: jsonParse, tag: tag, ); } ///统一网络请求 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[tag] 请求统一标识,用于取消网络请求 Future<T> _requestAsync<T>({ @required String url, String method, data, Map<String, dynamic> params, Options options, JsonParse<T> jsonParse, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { LogUtil.v("请求网络异常,请稍后重试!"); throw (HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } //设置默认值 params = params ?? {}; method = method ?? 'GET'; options?.method = method; options = options ?? Options( method: method, ); url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } Response<Map<String, dynamic>> response = await _client.request(url, queryParameters: params, data: data, options: options, cancelToken: cancelToken); String statusCode = response.data["statusCode"]; if (statusCode == "0") { //成功 if (jsonParse != null) { return jsonParse(response.data["data"]); } else { return response.data["data"]; } } else { //失败 String message = response.data["statusDesc"]; LogUtil.v("请求服务器出错:$message"); //只能用 Future,外层有 try catch return Future.error((HttpError(statusCode, message))); } } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); throw (HttpError.dioError(e)); } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); throw (HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } ///异步下载文件 /// ///[url] 下载地址 ///[savePath] 文件保存路径 ///[onReceiveProgress] 文件保存路径 ///[data] post 请求参数 ///[params] url请求参数支持restful ///[options] 请求配置 ///[tag] 请求统一标识,用于取消网络请求 Future<Response> downloadAsync({ @required String url, @required savePath, ProgressCallback onReceiveProgress, Map<String, dynamic> params, data, Options options, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { LogUtil.v("请求网络异常,请稍后重试!"); throw (HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } //设置下载不超时 int receiveTimeout = 0; options ??= options == null ? Options(receiveTimeout: receiveTimeout) : options.merge(receiveTimeout: receiveTimeout); //设置默认值 params = params ?? {}; url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } return _client.download(url, savePath, onReceiveProgress: onReceiveProgress, queryParameters: params, data: data, options: options, cancelToken: cancelToken); } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); throw (HttpError.dioError(e)); } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); throw (HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } ///上传文件 /// ///[url] 网络请求地址不包含域名 ///[data] post 请求参数 ///[onSendProgress] 上传进度 ///[params] url请求参数支持restful ///[options] 请求配置 ///[tag] 请求统一标识,用于取消网络请求 Future<T> uploadAsync<T>({ @required String url, FormData data, ProgressCallback onSendProgress, Map<String, dynamic> params, Options options, JsonParse<T> jsonParse, @required String tag, }) async { //检查网络是否连接 ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.none) { LogUtil.v("请求网络异常,请稍后重试!"); throw (HttpError(HttpError.NETWORK_ERROR, "网络异常,请稍后重试!")); } //设置默认值 params = params ?? {}; //强制 POST 请求 options?.method = POST; options = options ?? Options( method: POST, ); url = _restfulUrl(url, params); try { CancelToken cancelToken; if (tag != null) { cancelToken = _cancelTokens[tag] == null ? CancelToken() : _cancelTokens[tag]; _cancelTokens[tag] = cancelToken; } Response<Map<String, dynamic>> response = await _client.request(url, onSendProgress: onSendProgress, data: data, queryParameters: params, options: options, cancelToken: cancelToken); String statusCode = response.data["statusCode"]; if (statusCode == "0") { //成功 if (jsonParse != null) { return jsonParse(response.data["data"]); } else { return response.data["data"]; } } else { //失败 String message = response.data["statusDesc"]; LogUtil.v("请求服务器出错:$message"); return Future.error((HttpError(statusCode, message))); } } on DioError catch (e, s) { LogUtil.v("请求出错:$e/n$s"); throw (HttpError.dioError(e)); } catch (e, s) { LogUtil.v("未知异常出错:$e/n$s"); throw (HttpError(HttpError.UNKNOWN, "网络异常,请稍后重试!")); } } ///取消网络请求 void cancel(String tag) { if (_cancelTokens.containsKey(tag)) { if (!_cancelTokens[tag].isCancelled) { _cancelTokens[tag].cancel(); } _cancelTokens.remove(tag); } } ///restful处理 String _restfulUrl(String url, Map<String, dynamic> params) { // restful 请求处理 // /gysw/search/hist/:user_id user_id=27 // 最终生成 url 为 /gysw/search/hist/27 params.forEach((key, value) { if (url.indexOf(key) != -1) { url = url.replaceAll(':$key', value.toString()); } }); return url; } } 复制代码
这里内置了网络是否连接判断、取消网络请求、处理了默认的数据格式为
{ "data":{}, "statusCode":"0", "statusDesc":"02032008:用户授信未通过", "timestamp":1569206576392 } 复制代码
大家可根据自己的需求自行更改成自己的数据格式处理
import 'package:dio/dio.dart'; /// @desc 网络请求错误 /// @time 2019/3/20 10:02 AM /// @author Cheney class HttpError { ///HTTP 状态码 static const int UNAUTHORIZED = 401; static const int FORBIDDEN = 403; static const int NOT_FOUND = 404; static const int REQUEST_TIMEOUT = 408; static const int INTERNAL_SERVER_ERROR = 500; static const int BAD_GATEWAY = 502; static const int SERVICE_UNAVAILABLE = 503; static const int GATEWAY_TIMEOUT = 504; ///未知错误 static const String UNKNOWN = "UNKNOWN"; ///解析错误 static const String PARSE_ERROR = "PARSE_ERROR"; ///网络错误 static const String NETWORK_ERROR = "NETWORK_ERROR"; ///协议错误 static const String HTTP_ERROR = "HTTP_ERROR"; ///证书错误 static const String SSL_ERROR = "SSL_ERROR"; ///连接超时 static const String CONNECT_TIMEOUT = "CONNECT_TIMEOUT"; ///响应超时 static const String RECEIVE_TIMEOUT = "RECEIVE_TIMEOUT"; ///发送超时 static const String SEND_TIMEOUT = "SEND_TIMEOUT"; ///网络请求取消 static const String CANCEL = "CANCEL"; String code; String message; HttpError(this.code, this.message); HttpError.dioError(DioError error) { message = error.message; switch (error.type) { case DioErrorType.CONNECT_TIMEOUT: code = CONNECT_TIMEOUT; message = "网络连接超时,请检查网络设置"; break; case DioErrorType.RECEIVE_TIMEOUT: code = RECEIVE_TIMEOUT; message = "服务器异常,请稍后重试!"; break; case DioErrorType.SEND_TIMEOUT: code = SEND_TIMEOUT; message = "网络连接超时,请检查网络设置"; break; case DioErrorType.RESPONSE: code = HTTP_ERROR; message = "服务器异常,请稍后重试!"; break; case DioErrorType.CANCEL: code = CANCEL; message = "请求已被取消,请重新请求"; break; case DioErrorType.DEFAULT: code = UNKNOWN; message = "网络异常,请稍后重试!"; break; } } @override String toString() { return 'HttpError{code: $code, message: $message}'; } } 复制代码
这里设置的多种错误的描述,大家可根据需求自行修改
import 'package:dio/dio.dart'; import 'package:flutter_common_utils/log_util.dart'; void log2Console(Object object) { LogUtil.v(object); } /// @desc 自定义日志拦截器 ///@time 2019/3/18 9:15 AM /// @author Cheney class LogInterceptor extends Interceptor { LogInterceptor({ this.request = true, this.requestHeader = true, this.requestBody = false, this.responseHeader = true, this.responseBody = false, this.error = true, this.logPrint = log2Console, }); /// Print request [Options] bool request; /// Print request header [Options.headers] bool requestHeader; /// Print request data [Options.data] bool requestBody; /// Print [Response.data] bool responseBody; /// Print [Response.headers] bool responseHeader; /// Print error message bool error; /// Log printer; defaults print log to console. /// In flutter, you'd better use debugPrint. /// you can also write log in a file, for example: ///```dart /// var file=File("./log.txt"); /// var sink=file.openWrite(); /// dio.interceptors.add(LogInterceptor(logPrint: sink.writeln)); /// ... /// await sink.close(); ///``` void Function(Object object) logPrint; @override Future onRequest(RequestOptions options) async { logPrint('*** Request ***'); printKV('uri', options.uri); if (request) { printKV('method', options.method); printKV('responseType', options.responseType?.toString()); printKV('followRedirects', options.followRedirects); printKV('connectTimeout', options.connectTimeout); printKV('receiveTimeout', options.receiveTimeout); printKV('extra', options.extra); } if (requestHeader) { logPrint('headers:'); options.headers.forEach((key, v) => printKV(" $key", v)); } if (requestBody) { logPrint("data:"); printAll(options.data); } logPrint(""); } @override Future onError(DioError err) async { if (error) { logPrint('*** DioError ***:'); logPrint("uri: ${err.request.uri}"); logPrint("$err"); if (err.response != null) { _printResponse(err.response); } logPrint(""); } } @override Future onResponse(Response response) async { logPrint("*** Response ***"); _printResponse(response); } void _printResponse(Response response) { printKV('uri', response.request?.uri); if (responseHeader) { printKV('statusCode', response.statusCode); if (response.isRedirect == true) { printKV('redirect', response.realUri); } if (response.headers != null) { logPrint("headers:"); response.headers.forEach((key, v) => printKV(" $key", v.join(","))); } } if (responseBody) { logPrint("Response Text:"); printAll(response.toString()); } logPrint(""); } printKV(String key, Object v) { logPrint('$key: $v'); } printAll(msg) { msg.toString().split("/n").forEach(logPrint); } } 复制代码
这里默认使用 LogUtl 输出日志,大家可根据需要换成自己的日志输出工具类
//初始化 Http, HttpManager().init( baseUrl: Api.getBaseUrl(), interceptors: [ HeaderInterceptor(), LogInterceptor(), ], ); 复制代码
///同步回调模式 ///get 网络请求 void _get(){ HttpManager().get( url: "/app/info", params: {"iouCode": iouCode}, successCallback: (data) { }, errorCallback: (HttpError error) { }, tag: "tag", ); } ///post 网络请求 void _post(){ HttpManager().post( url: "/app/info", data: {"iouCode": iouCode}, successCallback: (data) { }, errorCallback: (HttpError error) { }, tag: "tag", ); } ///下载文件 void _download(){ HttpManager().download( url: "/app/download", savePath: "/savePath", onReceiveProgress: (int count, int total) { }, successCallback: (data) { }, errorCallback: (HttpError error) { }, tag: tag, ); } ///上传文件 void _upload() async{ FormData data = FormData.fromMap({ "file": await MultipartFile.fromFile(path, filename: "$photoTime"), }); HttpManager().upload( url: "/app/upload", data: data, tag: "tag", successCallback: (data) { }, errorCallback: (HttpError error) { }, ); } ///异步模式 ///get 请求 void _getAysnc() async{ String timestamp = await HttpManager().getAsync(url: "/app/info", tag: "syncTime"); } ///post 请求 void _postAysnc() async{ await HttpManager().postAsync( url: "app/info", tag: "tag", data: { 'bannerTypes': ["wealthBanner"], }, jsonParse: (json) => Pager(json, (data) => ImageAd(data))) } ///下载文件 void _downloadAsync() async{ await HttpManager().downloadAsync( url: "/app/download", savePath: "/savePath", onReceiveProgress: (int count, int total) { }, tag: "tag", ); } ///上传文件 void _uploadAsync() async{ FormData data = FormData.fromMap({ "file": await MultipartFile.fromFile(path, filename: "$photoTime"), }); await HttpManager().uploadAsync( url: "/app/upload", data: data, tag: "tag", ); } 复制代码