Flutter實(shí)戰(zhàn) Http請求-Dio http庫

2021-03-09 10:10 更新

通過上一節(jié)介紹,我們可以發(fā)現(xiàn)直接使用 HttpClient 發(fā)起網(wǎng)絡(luò)請求是比較麻煩的,很多事情得我們手動處理,如果再涉及到文件上傳/下載、Cookie 管理等就會非常繁瑣。幸運(yùn)的是,Dart 社區(qū)有一些第三方 http 請求庫,用它們來發(fā)起 http 請求將會簡單的多,本節(jié)我們介紹一下目前人氣較高的dio (opens new window)庫。

dio 是一個強(qiáng)大的 Dart Http 請求庫,支持 Restful API、FormData、攔截器、請求取消、Cookie 管理、文件上傳/下載、超時等。dio 的使用方式隨著其版本升級可能會發(fā)生變化,如果本節(jié)所述內(nèi)容和 dio 官方有差異,請以 dio 官方文檔為準(zhǔn)。

#引入

引入 dio:

  1. dependencies:
  2. dio: ^x.x.x #請使用pub上的最新版本

導(dǎo)入并創(chuàng)建 dio 實(shí)例:

  1. import 'package:dio/dio.dart';
  2. Dio dio = Dio();

接下來就可以通過 dio 實(shí)例來發(fā)起網(wǎng)絡(luò)請求了,注意,一個 dio 實(shí)例可以發(fā)起多個 http 請求,一般來說,APP 只有一個 http 數(shù)據(jù)源時,dio 應(yīng)該使用單例模式。

#示例

發(fā)起 GET 請求 :

  1. Response response;
  2. response=await dio.get("/test?id=12&name=wendu")
  3. print(response.data.toString());

對于GET請求我們可以將 query 參數(shù)通過對象來傳遞,上面的代碼等同于:

  1. response=await dio.get("/test",queryParameters:{"id":12,"name":"wendu"})
  2. print(response);

發(fā)起一個 POST 請求:

  1. response=await dio.post("/test",data:{"id":12,"name":"wendu"})

發(fā)起多個并發(fā)請求:

  1. response= await Future.wait([dio.post("/info"),dio.get("/token")]);

下載文件:

  1. response=await dio.download("https://www.google.com/",_savePath);

發(fā)送 FormData:

  1. FormData formData = new FormData.from({
  2. "name": "wendux",
  3. "age": 25,
  4. });
  5. response = await dio.post("/info", data: formData)

如果發(fā)送的數(shù)據(jù)是 FormData,則 dio 會將請求 header 的contentType設(shè)為“multipart/form-data”。

通過 FormData 上傳多個文件:

  1. FormData formData = new FormData.from({
  2. "name": "wendux",
  3. "age": 25,
  4. "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
  5. "file2": new UploadFileInfo(new File("./upload.txt"), "upload2.txt"),
  6. // 支持文件數(shù)組上傳
  7. "files": [
  8. new UploadFileInfo(new File("./example/upload.txt"), "upload.txt"),
  9. new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
  10. ]
  11. });
  12. response = await dio.post("/info", data: formData)

值得一提的是,dio 內(nèi)部仍然使用 HttpClient 發(fā)起的請求,所以代理、請求認(rèn)證、證書校驗(yàn)等和 HttpClient 是相同的,我們可以在onHttpClientCreate回調(diào)中設(shè)置,例如:

  1. (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
  2. //設(shè)置代理
  3. client.findProxy = (uri) {
  4. return "PROXY 192.168.1.2:8888";
  5. };
  6. //校驗(yàn)證書
  7. httpClient.badCertificateCallback=(X509Certificate cert, String host, int port){
  8. if(cert.pem==PEM){
  9. return true; //證書一致,則允許發(fā)送數(shù)據(jù)
  10. }
  11. return false;
  12. };
  13. };

注意,onHttpClientCreate會在當(dāng)前 dio 實(shí)例內(nèi)部需要創(chuàng)建 HttpClient 時調(diào)用,所以通過此回調(diào)配置 HttpClient 會對整個 dio 實(shí)例生效,如果你想針對某個應(yīng)用請求單獨(dú)的代理或證書校驗(yàn)策略,可以創(chuàng)建一個新的 dio 實(shí)例即可。

怎么樣,是不是很簡單,除了這些基本的用法,dio 還支持請求配置、攔截器等,官方資料比較詳細(xì),故本書不再贅述,詳情可以參考dio 主頁 。 下一節(jié)我們將使用 dio 實(shí)現(xiàn)一個分塊下載器。

#實(shí)例

我們通過 Github 開放的 API 來請求 flutterchina 組織下的所有公開的開源項(xiàng)目,實(shí)現(xiàn):

  1. 在請求階段彈出 loading
  2. 請求結(jié)束后,如果請求失敗,則展示錯誤信息;如果成功,則將項(xiàng)目名稱列表展示出來。

代碼如下:

  1. class _FutureBuilderRouteState extends State<FutureBuilderRoute> {
  2. Dio _dio = new Dio();
  3. @override
  4. Widget build(BuildContext context) {
  5. return new Container(
  6. alignment: Alignment.center,
  7. child: FutureBuilder(
  8. future: _dio.get("https://api.github.com/orgs/flutterchina/repos"),
  9. builder: (BuildContext context, AsyncSnapshot snapshot) {
  10. //請求完成
  11. if (snapshot.connectionState == ConnectionState.done) {
  12. Response response = snapshot.data;
  13. //發(fā)生錯誤
  14. if (snapshot.hasError) {
  15. return Text(snapshot.error.toString());
  16. }
  17. //請求成功,通過項(xiàng)目信息構(gòu)建用于顯示項(xiàng)目名稱的ListView
  18. return ListView(
  19. children: response.data.map<Widget>((e) =>
  20. ListTile(title: Text(e["full_name"]))
  21. ).toList(),
  22. );
  23. }
  24. //請求未完成時彈出loading
  25. return CircularProgressIndicator();
  26. }
  27. ),
  28. );
  29. }
  30. }
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號