一. 網(wǎng)絡(luò)請求的方式
在Flutter中常見的網(wǎng)絡(luò)請求方式有三種:HttpClient巫湘、http庫哈雏、dio庫卓起;
1.1. HttpClient
HttpClient是dart自帶的請求類,在io包中盾饮,實現(xiàn)了基本的網(wǎng)絡(luò)請求相關(guān)的操作采桃。
網(wǎng)絡(luò)調(diào)用通常遵循如下步驟:
- 創(chuàng)建 client
- 構(gòu)造 Uri
- 發(fā)起請求懒熙,等待請求,同時您也可以配置請求headers普办、 body
- 關(guān)閉請求工扎,等待響應(yīng)
- 解碼響應(yīng)的內(nèi)容
網(wǎng)絡(luò)請求實例:
void requestNetwork() async {
// 1.創(chuàng)建HttpClient對象
final httpClient = HttpClient();
// 2.構(gòu)建請求的uri
final uri = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");
// 3.構(gòu)建請求
final request = await httpClient.getUrl(uri);
// 4.發(fā)送請求,必須
final response = await request.close();
if (response.statusCode == HttpStatus.ok) {
print(await response.transform(utf8.decoder).join());
} else {
print(response.statusCode);
}
}
其實HttpClient也可以發(fā)送post相關(guān)的請求衔蹲,我們這里就不再演練肢娘。
HttpClient雖然可以發(fā)送正常的網(wǎng)絡(luò)請求,但是會暴露過多的細(xì)節(jié):比如需要主動關(guān)閉request請求舆驶,拿到數(shù)據(jù)后也需要手動的進(jìn)行字符串解碼橱健。
在開發(fā)中,我們一般很少直接面向HttpClient進(jìn)行網(wǎng)絡(luò)請求沙廉,而是使用一些庫來完成畴博。
1.2. http庫
http 是 Dart 官方提供的另一個網(wǎng)絡(luò)請求類,相比于 HttpClient蓝仲,易用性提升了不少。但是官疲,沒有默認(rèn)集成到Dart的SDK中袱结,所以我們需要先在pubspec中依賴它:
http: ^0.12.0+2
導(dǎo)入并且使用即可:
import 'package:http/http.dart' as http;
void httpNetwork() async {
// 1.創(chuàng)建Client
final client = http.Client();
// 2.構(gòu)建uri
final url = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");
// 3.發(fā)送請求
final response = await client.get(url);
// 4.獲取結(jié)果
if (response.statusCode == HttpStatus.ok) {
print(response.body);
} else {
print(response.statusCode);
}
}
1.3. dio三方庫
官方提供的HttpClient和http都可以正常的發(fā)送網(wǎng)絡(luò)請求,但是對于現(xiàn)代的應(yīng)用程序開發(fā)來說途凫,我們通常要求的東西會更多:比如攔截器垢夹、取消請求、文件上傳/下載维费、超時設(shè)置等等果元;
這個時候,我們可以使用一個在Flutter中非常流行的三方庫:dio犀盟,官網(wǎng)有對dio進(jìn)行解釋:
dio是一個強(qiáng)大的Dart Http請求庫而晒,支持Restful API、FormData阅畴、攔截器倡怎、請求取消、Cookie管理贱枣、文件上傳/下載监署、超時、自定義適配器等...
使用dio三方庫必然也需要先在pubspec中依賴它:
dio: ^3.0.1
終端執(zhí)行pub get
纽哥,導(dǎo)入并使用:
import 'package:dio/dio.dart';
void dioNetwork() async {
// 1.創(chuàng)建Dio請求對象
final dio = Dio();
// 2.發(fā)送網(wǎng)絡(luò)請求
final response = await dio.get("http://123.207.32.32:8000/api/v1/recommend");
// 3.打印請求結(jié)果
if (response.statusCode == HttpStatus.ok) {
print(response.data);
} else {
print("請求失斈品Α:${response.statusCode}");
}
}
補(bǔ)充:一個很好用的網(wǎng)站:https://httpbin.org/get
,后面跟get春塌、post等可以測試網(wǎng)絡(luò)庫的使用晓避。
1.4. dio庫的封裝
http_config.dart文件:
class HttpConfig {
static const String baseURL = "https://httpbin.org";
static const int timeout = 5000;
}
http_request.dart文件:
import 'package:dio/dio.dart';
import 'package:testflutter001/service/http_config.dart';
class HttpRequest {
static final BaseOptions options = BaseOptions(
baseUrl: HTTPConfig.baseURL, connectTimeout: HTTPConfig.timeout);
static final 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.在進(jìn)行任何網(wǎng)絡(luò)請求的時候, 可以添加一個loading顯示
// 2.很多頁面的訪問必須要求攜帶Token,那么就可以在這里判斷是有Token
// 3.對參數(shù)進(jìn)行一些處理,比如序列化處理等
print("攔截了請求");
return options;
},
onResponse: (Response response) {
print("攔截了響應(yīng)");
return response;
},
onError: (DioError error) {
print("攔截了錯誤");
return error;
}
);
List<Interceptor> inters = [dInter];
// 添加用戶傳的攔截器
if (inter != null) {
inters.add(inter);
}
// 統(tǒng)一添加攔截器
dio.interceptors.addAll(inters);
// 3.發(fā)送網(wǎng)絡(luò)請求
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);
});