Flutter(七)之網絡請求

一. 網絡請求的方式

在Flutter中常見的網絡請求方式有三種:HttpClient、http庫、dio庫;

1.1. HttpClient

HttpClient是dart自帶的請求類,在io包中,實現了基本的網絡請求相關的操作。

網絡調用通常遵循如下步驟:

  1. 創建 client.
  2. 構造 Uri.
  3. 發起請求, 等待請求,同時您也可以配置請求headers、 body。
  4. 關閉請求, 等待響應.
  5. 解碼響應的內容.

網絡請求實例:

void requestNetwork() async {
  // 1.創建HttpClient對象
  final httpClient = HttpClient();

  // 2.構建請求的uri
  final uri = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");

  // 3.構建請求
  final request = await httpClient.getUrl(uri);

  // 4.發送請求,必須
  final response = await request.close();
  if (response.statusCode == HttpStatus.ok) {
    print(await response.transform(utf8.decoder).join());
  } else {
    print(response.statusCode);
  }
}

OK,其實HttpClient也可以發送post相關的請求,我們這裏就不再演練。

HttpClient雖然可以發送正常的網絡請求,但是會暴露過多的細節:

  • 比如需要主動關閉request請求,拿到數據後也需要手動的進行字符串解碼
    在開發中,我們一般很多直接面向HttpClient進行網絡請求,而是使用一些庫來完成。

1.2. http庫

http 是 Dart 官方提供的另一個網絡請求類,相比於 HttpClient,易用性提升了不少。

但是,沒有默認集成到Dart的SDK中,所以我們需要先在pubspec中依賴它:

 http:^0.12.0+2

導入並且使用即可

import'package:http/http.dart'as http;

void httpNetwork() async {
  // 1.創建Client
  final client = http.Client();

  // 2.構建uri
  final url = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");

  // 3.發送請求
  final response = await client.get(url);

  // 4.獲取結果
  if (response.statusCode == HttpStatus.ok) {
    print(response.body);
  } else {
    print(response.statusCode);
  }
}

1.3. dio三方庫

官方提供的HttpClient和http都可以正常的發送網絡請求,但是對於現代的應用程序開發來說,我們通常要求的東西會更多:比如攔截器、取消請求、文件上傳/下載、超時設置等等;

這個時候,我們可以使用一個在Flutter中非常流行的三方庫:dio

官網有對dio進行解釋:

dio是一個強大的Dart Http請求庫,支持Restful API、FormData、攔截器、請求取消、Cookie管理、文件上傳/下載、超時、自定義適配器等…

使用dio三方庫必然也需要先在pubspec中依賴它:

dio:^3.0.1

代碼演練:

import'package:dio/dio.dart';

void dioNetwork() async {
  // 1.創建Dio請求對象
  final dio = Dio();

  // 2.發送網絡請求
  final response = await dio.get("http://123.207.32.32:8000/api/v1/recommend");

  // 3.打印請求結果
  if (response.statusCode == HttpStatus.ok) {
    print(response.data);
  } else {
    print("請求失敗:${response.statusCode}");
  }
}

1.4. dio庫的封裝

http_config.dart

class HTTPConfig {
  staticconst baseURL = "https://httpbin.org";
  staticconst timeout = 5000;
}

http_request.dart

import'package:dio/dio.dart';
import'package:testflutter001/service/config.dart';

class HttpRequest {
  staticfinal BaseOptions options = BaseOptions(
      baseUrl: HTTPConfig.baseURL, connectTimeout: HTTPConfig.timeout);
  staticfinal Dio dio = Dio(options);

  static Future<T> request<T>(String url,
      {String method = 'get', Map<String, dynamic> params, Interceptor inter}) async {
    // 1.請求的單獨配置
    final options = Options(method: method);

    // 2.添加第一個攔截器
    Interceptor dInter = InterceptorsWrapper(
      onRequest: (RequestOptions options) {
        // 1.在進行任何網絡請求的時候, 可以添加一個loading顯示

        // 2.很多頁面的訪問必須要求攜帶Token,那麼就可以在這裏判斷是有Token

        // 3.對參數進行一些處理,比如序列化處理等
        print("攔截了請求");
        return options;
      },
      onResponse: (Response response) {
        print("攔截了響應");
        return response;
      },
      onError: (DioError error) {
        print("攔截了錯誤");
        return error;
      }
    );
    List<Interceptor> inters = [dInter];
    if (inter != null) {
      inters.add(inter);
    }
    dio.interceptors.addAll(inters);

    // 3.發送網絡請求
    try {
      Response response = await dio.request<T>(url, queryParameters: params, options: options);
      return response.data;
    } on DioError catch(e) {
      return Future.error(e);
    }
  }
}

代碼使用:

HttpRequest.request("https://httpbin.org/get", params: {"name": "why", 'age': 18}).then((res) {
  print(res);
});

HttpRequest.request("https://httpbin.org/post",
                    method: "post", params: {"name": "why", 'age': 18}).then((res) {
  print(res);
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章