Flutter 使用dio來發起網絡請求以及Cookie管理

說點兒閒話

Flutter官方建議您使用 dio 來發起網絡請求,在學習過程當中,也嘗試過用dart io中的HttpClient發起的請求,這裏主要講一下dio的使用以及CookieJarCookieManager管理cookiehtml

dio

dio是一個強大易用的dart http請求庫,支持Restful APIFormData、攔截器、請求取消、Cookie管理、文件上傳/下載……詳情請查看 github dio
最新版本請查看:pub.dev diogit

pubspec.yaml文件裏添加:github

dio: ^3.x.x  // 請使用pub上3.0.0分支的最新版本

建立一個Dio實例,並配置它

建議在項目中使用Dio單例,這樣即可對同一個dio實例發起的全部請求進行一些統一的配置,好比設置公共header、請求基地址、超時時間等;

在這裏,baseUrl 須要單首創建一個共用的BaseUrl.url後端

class BaseUrl {
  // 配置默認請求地址
  static String url = 'http://xxxxx/'; // 測試環境
}

BaseUrl.url也方便後面Cookie管理用到。cookie

使用默認配置:網絡

Dio dio \= Dio(); // 使用默認配置

// 配置dio實例
dio.options.baseUrl \= BaseUrl.url;
dio.options.connectTimeout \= 5000; //5s
dio.options.receiveTimeout \= 3000;

或者app

// 經過傳遞一個 \`options\`來建立dio實例
Options options \= BaseOptions(
    baseUrl: BaseUrl.url,
    connectTimeout: 5000,
    receiveTimeout: 3000,
);
Dio dio \= Dio(options);

發起請求及響應數據

發起一個GET請求 :async

Response response;
Dio dio \= 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());

發起一個POST請求:ide

response \= await dio.post("/test", data: {"id": 12, "name": "wendu"});
try {
    Response response \= await dio.get("https://www.google.com");
    print(response.data);
    print(response.headers);
    print(response.request);
    print(response.statusCode);
  } on DioError catch (e) {
    //catch 提示
    print('catch 提示: ' + e.toString());
  } finally {
  }

CookieJar 和 CookieManager

github CookieJar
pub.dev cookie_jarpost

github dio_cookie_manager
pub.dev dio_cookie_manager

pubspec.yaml文件裏添加:

cookie_jar: ^1.0.x  #latest version
dio_cookie_manager: ^1.0.x  #latest version
import 'package:flutter/material.dart';
import 'package:cookie_jar/cookie_jar.dart';

class Api {  
  static final CookieJar cookieJar = new CookieJar();
  
}

在項目中其餘全部的dart文件中使用:

List<Cookie> cookies = [
   new Cookie("xxx", xxx),
   // ....
];
//Save cookies            
Api.cookieJar.saveFromResponse(Uri.parse(BaseUrl.url), cookies);

//獲取cookies   
List<Cookie> cookies = Api.cookieJar.loadForRequest(Uri.parse(BaseUrl.url));
 // print(cookies);

須要注意的是,通常咱們的項目中登陸接口調用成功後,後端會在cookie中寫入token,因此登陸請求前先創建CookieManager來自動管理cookie:

import 'package:dio_cookie_manager/dio_cookie_manager.dart';

dio.interceptors.add(CookieManager(await Api.cookieJar));

一開始,我在app中使用的上述方法存cookie,開發過程當中都是flutter run運行的,後來打包測試,發現後臺殺掉app時,獲取不到cookie了,這才注意到:

CookieJarcookie保存在RAM中,所以,若是應用程序退出,則將清除全部cookie

因而,改成使用下面的PersistCookieJar

PersistCookieJar

PersistCookieJar將cookie保存在文件中,所以,若是應用程序退出,則cookie始終存在,除非顯式調用delete

將上述Api中的CookieJar()改成PersistCookieJar

注意:在flutter中,傳遞給PersistCookieJar的路徑必須有效(存在於電話中並具備寫訪問權限)。您可使用 path_provider來獲取正確的路徑。

pubspec.yaml文件裏添加:

path\_provider: ^1.0.x  #latest version
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:path_provider/path_provider.dart';

class Api { 
  //改成使用 PersistCookieJar,在文檔中有介紹,PersistCookieJar將cookie保留在文件中,所以,若是應用程序退出,則cookie始終存在,除非顯式調用delete
  static PersistCookieJar _cookieJar;
  static Future<PersistCookieJar> get cookieJar async {
      // print(_cookieJar);
    if (_cookieJar == null) {
      Directory appDocDir = await getApplicationDocumentsDirectory();
      String appDocPath  = appDocDir.path;
      print('獲取的文件系統目錄 appDocPath: ' + appDocPath);
      _cookieJar = new PersistCookieJar(dir: appDocPath);
    }
    return _cookieJar;
  }
}

在項目中其餘全部的dart文件中使用改成:

List<Cookie> cookies = [
   new Cookie("xxx", xxx),
   // ....
];
//Save cookies            
(await Api.cookieJar).saveFromResponse(Uri.parse(BaseUrl.url), cookies);

//獲取cookies   
List<Cookie> cookies = (await Api.cookieJar).loadForRequest(Uri.parse(BaseUrl.url));
 // print(cookies);

創建CookieManager來自動管理cookie的代碼不改變。

參考資料

dio
Http請求-Dio http庫
github CookieJar
pub.dev cookie_jar
github dio_cookie_manager
pub.dev dio_cookie_manager
path_provider
Flutter用dio封裝http網絡請求,設置統一的請求地址、headers及處理返回內容

相關文章
相關標籤/搜索