不得不说的DIO
Flutter網絡框架DIO的基本使用
1.基本概念
dio是一個強大的Dart Http請求庫,支持Restful API、FormData、攔截器、請求取消、Cookie管理、文件上傳/下載、超時、自定義適配器等…
2.簡單示例代碼
import 'package:dio/dio.dart'; main() async {var dio = Dio();Response response = await dio.get("https://google.com");print(response.data); }3.添加依賴
在pubspec.yaml文件中添加:
dependencies:dio: 2.1.13 #當前最新版本為2.1.134.DIO常見內容列表
- 使用application/x-www-form-urlencoded編碼
-
請求示例(get、post)
1、發起get請求
Response response; Dio dio = new Dio(); response = await dio.get("/test?id=12&name=wendu"); print(response.data.toString()); // 請求參數也可以通過對象傳遞,上面的代碼等同于: response = await dio.get("/test", queryParameters: {"id": 12, "name": "wendu"}); print(response.data.toString());2、發起POST請求
- 普通post方式
- FormData的post請求方式:
Dio支持發送 FormData, 請求數據將會以 multipart/form-data方式編碼, FormData中可以一個或多個包含文件
注意: 只有 post 方法支持發送 FormData.
FormData formData = new FormData.from({"name": "wendux","age": 25, }); response = await dio.post("/info", data: formData);- FormData上傳多個文件
3、發起并發請求
response = await Future.wait([dio.post("/info"), dio.get("/token")]);4、下載文件
response = await dio.download("https://www.google.com/", "./xx.html");5、請求接收方式
- a.流形式接收
- b.二進制接收
6.監聽發送(上傳)數據速度
response = await dio.post( "http://www.dtworkroom.com/doris/1/2.0.0/test", data: {"aa": "bb" * 22}, onSendProgress: (int sent, int total) { print("$sent $total"); }, );7.以流的形式提交二進制數據
// 二進制數據 List<int> postData = <int>[...]; await dio.post( url, data: Stream.fromIterable(postData.map((e) => [e])), //創建一個Stream<List<int>> options: Options(headers: {HttpHeaders.contentLengthHeader: postData.length, // 設置content-length}, ), ); 如果要監聽提交進度,則必須設置content-length,反之則是可選的。 -
Dio APIs
DIO核心API代碼如下:
Future request(String path, {data,Map queryParameters, Options options,CancelToken cancelToken, ProgressCallback onSendProgress, ProgressCallback onReceiveProgress)response = await request("/test",data: {"id": 12, "name": "xx"},options: Options(method: "GET"),);建議在項目中使用Dio單例,這樣便可對同一個dio實例發起的所有請求進行一些統一的配置,比如設置公共header、請求基地址、超時時間等
我們可以使用默認配置或傳遞一個可選BaseOptions參數來創建一個Dio實例
Dio dio = new Dio(); // 使用默認配置// 配置dio實例dio.options.baseUrl = "https://www.xx.com/api";dio.options.connectTimeout = 5000; //5sdio.options.receiveTimeout = 3000;// 或者通過傳遞一個 `BaseOptions`來創建dio實例BaseOptions options = new BaseOptions(baseUrl: "https://www.xx.com/api",connectTimeout: 5000,receiveTimeout: 3000,);Dio dio = new Dio(options);- 請求配置
下面是所有的請求配置選項。 如果請求method沒有指定,則默認為GET :
{/// Http method.String method;/// 請求基地址,可以包含子路徑,如: "https://www.google.com/api/".String baseUrl;/// Http請求頭.Map<String, dynamic> headers;/// 連接服務器超時時間,單位是毫秒.int connectTimeout;/// 2.x中為接收數據的最長時限.int receiveTimeout;/// 請求路徑,如果 `path` 以 "http(s)"開始, 則 `baseURL` 會被忽略; 否則,/// 將會和baseUrl拼接出完整的的url.String path = "";/// 請求的Content-Type,默認值是[ContentType.JSON]./// 如果您想以"application/x-www-form-urlencoded"格式編碼請求數據,/// 可以設置此選項為 `ContentType.parse("application/x-www-form-urlencoded")`, 這樣[Dio]/// 就會自動編碼請求體.ContentType contentType;/// [responseType] 表示期望以那種格式(方式)接受響應數據。/// 目前 [ResponseType] 接受三種類型 `JSON`, `STREAM`, `PLAIN`.////// 默認值是 `JSON`, 當響應頭中content-type為"application/json"時,dio 會自動將響應內容轉化為json對象。/// 如果想以二進制方式接受響應數據,如下載一個二進制文件,那么可以使用 `STREAM`.////// 如果想以文本(字符串)格式接收響應數據,請使用 `PLAIN`.ResponseType responseType;/// `validateStatus` 決定http響應狀態碼是否被dio視為請求成功, 返回`validateStatus`/// 返回`true` , 請求結果就會按成功處理,否則會按失敗處理.ValidateStatus validateStatus;/// 用戶自定義字段,可以在 [Interceptor]、[Transformer] 和 [Response] 中取到.Map<String, dynamic> extra;/// 公共query參數Map<String, dynamic /*String|Iterable<String>*/ > queryParameters; }- 響應數據
當請求成功時會返回一個Response對象,它包含如下字段
{/// 響應數據,可能已經被轉換了類型, 詳情請參考Options中[ResponseType].var data;/// 響應頭HttpHeaders headers;/// 本次請求信息Options request;/// Http status code.int statusCode;/// 是否重定向bool isRedirect; /// 重定向信息 List<RedirectInfo> redirects ;/// 最終真正的請求地址(因為可能會重定向)Uri realUri; /// 響應對象的自定義字段(可以在攔截器中設置它),調用方可以在`then`中獲取.Map<String, dynamic> extra;//注:假如有一個url返回的是json數據,返回數據在默認情況下(options.responseType為json)會被自動轉為Json對象(Map或List)的: }以請求Google為例:
Response response = await dio.get("https://www.google.com");print(response.data);print(response.headers);print(response.request);print(response.statusCode);- 攔截器
我們在網絡請求中往往需要查看日志信息,此時就需要添加一個日志攔截器
dio.interceptors.add(LogInterceptor(responseBody: false)); //開啟請求日志 在添加攔截器時需要注意,由于攔截器隊列的執行順序是FIFO,如果把log攔截器添加到了最前面,則后面攔截器對options的更改就不會被打印(但依然會生效),所以建議把log攔截添加到隊尾。- Cookie管理
有時在進行請求中需要攔截cookie來自動管理請求/響應cookie,那么就需要添加依賴
dependencies:cookie_jar: ^1.0.1 你可以創建一個CookieJar 或 PersistCookieJar 來幫您自動管理cookie, dio 默認使用 CookieJar , 它會將cookie保存在內存中。 如果您想對cookie進行持久化, 請使用 PersistCookieJar , 示例代碼如下: var dio = new Dio(); dio.interceptors.add(CookieManager(CookieJar()))普遍說來,如果需要創建一些自定義的攔截器,只需要通過繼承Intercepto類來實現即可
- 錯誤處理
當請求過程中發生錯誤時, Dio 會包裝 Error/Exception 為一個 DioError:
try {//404await dio.get("https://wendux.github.io/xsddddd");} on DioError catch (e) {// The request was made and the server responded with a status code// that falls out of the range of 2xx and is also not 304.if (e.response) {print(e.response.data);print(e.response.headers);print(e.response.request);} else {// Something happened in setting up or sending the request that triggered an Errorprint(e.request);print(e.message);}}DioError字段
{/// 響應信息, 如果錯誤發生在在服務器返回數據之前,它為 `null`Response response;/// 錯誤描述.String message;/// 錯誤類型,見下文DioErrorType type;///原始的error或exception對象,通常type為DEFAULT時存在。dynamic error;/// 錯誤棧信息,可能為nullStackTrace stackTrace; }- 設置Http代理
- 請求取消
可以通過 cancel token 來取消發起的請求:
CancelToken token = new CancelToken(); dio.get(url, cancelToken: token).catchError((DioError err){if (CancelToken.isCancel(err)) {print('Request canceled! '+ err.message)}else{// handle error.}}); // cancel the requests with "cancelled" message. token.cancel("cancelled");總結
- 上一篇: 【日常开发必备】1.5W+字的 MySQ
- 下一篇: 用友U9 SOA引领企业IT架构全面升级