一. 網絡請求的方式
在Flutter中常見的網絡請求方式有三種:HttpClient、http庫、dio庫;
1.1. HttpClient
HttpClient是dart自帶的請求類,在io包中,實現了基本的網絡請求相關的操作。
網絡調用通常遵循如下步驟:
- 創建 client.
- 構造 Uri.
- 發起請求, 等待請求,同時您也可以配置請求headers、 body。
- 關閉請求, 等待響應.
- 解碼響應的內容.
網絡請求實例:
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);
});