http_request
- HttpClient: 是dart自带的请求类、在io包中
- http库:http库是Dart官方提供的另外一种网络请求类, 但需要手动添加依赖pubspec
- dio库:是flutter比较受欢迎的一个第三方库,需要手动添加依赖pubspec
1. HttpClient
/* HttpClient
是dart自带的请求类、在io包中
实现了基本的网络请求相关的操作。
1. 创建client
2. 构造url
3. 发起请求、等待请求、同时也可以配置请求header、body
4. 关闭请求、等待响应
5. 解析返回的内容
从下面可以看出来HttpClient 虽然可以发送正常的网络请求、但是会暴露更多细节:
> 需要主动关闭request.close
> 拿到数据需要手动的进行字符串解码
So. 在开发中我们一般使用一些库来完成。
*/
- http_client.dart
- 需要主动关闭request.close
- 拿到数据需要手动的进行字符串解码
import 'dart:convert';
import 'dart:io';
void requestNetworking() async {
// 1. 创建httpclient
final httpClient = HttpClient();
// 2.构建url
final url = Uri.parse('http://123.207.32.32:8000/api/v1/recommend');
// 3. 构建请求
final request = await httpClient.getUrl(url);
// 4. 发送请求、必须先关闭request
final response = await request.close();
if (response.statusCode == HttpStatus.ok) {
final result = await response.transform(utf8.decoder).join();
print('响应成功: $result');
} else {
print('!ok: ${response.statusCode}');
}
}
2. http库
/* http库
http库是Dart官方提供的另外一种网络请求类、相比于HttpClient, 易用性能提升了不少
但是没有默认集成到Dart SDK中、需要手动在依赖pubspec中手动添加 如http: ^0.12.0+2
https://pub.flutter-io.cn/packages/http/versions
http:
相比于HttpClient:
- 不需要手动关闭request.close
- 不需要手动去解析字符串解码
*/
import 'dart:io';
import 'package:http/http.dart' as http;
void httpNetworking() async {
// 1. 创建client
final client = http.Client();
// 2. 构建url
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('http-response: ${response.body}');
} else {
print('http-!ok: ${response.statusCode}');
}
}
3. dio 库
- 结果直接解析出中文
- 不需要手动关闭request
- 不需要手动解码结果字符串
- 使用到额外的功能很简单,比如拦截器、超时设置、取消请求、文件下载/上传等。
/* dio
官网提供的HttpClient & http 都可以正常发送网络请求、但是对于现代的应用程序开发来说
我们通常需要做很多操作:如拦截器、取消请求、文件上传/下载、超时设置等等
我们可以使用一个flutter第三方库dio
- dio是一个强大的Dart Http请求
*/
import 'dart:io';
import 'package:dio/dio.dart';
void dioNetworking() 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('success-dio: ${response.data} \n$response');
} else {
print('failure-dio: ${response.statusCode}');
}
}
4. dio库封装
class HTTPConfig {
static const baseURL = "https://httpbin.org";
static const timeout = 5000;
}
import 'package:dio/dio.dart';
import 'package:flutter_networking/dio/http_config.dart';
class HTTPRequest {
// 基本的options,比如超时时间、基本的url
static final BaseOptions baseOptions = BaseOptions(
baseUrl: HTTPConfig.baseURL,
connectTimeout: HTTPConfig.timeout,
headers: {},
);
static final Dio dio = Dio(baseOptions);
static Future<T> request<T>(
String url, {
String method = 'get',
Map<String, dynamic>? params,
Interceptor? inter,
}) async {
// 1. 请求的单独配置, 比如请求类型type:
final options = Options(method: method);
// 2. 添加第一个拦截器
Interceptor interceptor = InterceptorsWrapper(
onRequest: (options, handler) {
// 2.1: 在进行任何网络请求的时候、可以添加一个loading展示
// 2.2: 很多页面的访问必须要求携带token、那么就可以在这里判断是否有token
// 2.3: 对参数进行一些处理、比如系列化处理等
// flutter: ========> 拦截了请求request: https://httpbin.org/post?name=bmw&age=4, handler:Instance of 'RequestInterceptorHandler'
print('========> 拦截了请求request: ${options.uri}, handler:$handler');
return handler.next(options);
},
onResponse: (response, handler) {
print('\n========>拦截了响应response: $response, handler:$handler');
return handler.next(response);
},
onError: (error, handler) {
print('\n=========>拦截了错误error: $error, handler: $handler');
return handler.next(error);
},
);
List<Interceptor> inters = [interceptor];
if (inter != null) {
inters.add(inter);
}
dio.interceptors.addAll(inters);
print('list: ${inters.length}');
// 3. 发送网络请求
try {
Response response =
await dio.request<T>(url, queryParameters: params, options: options);
return response.data;
} on DioError catch (e) {
return Future.error(e);
}
}
}
5. http_request 使用
import 'package:flutter/material.dart';
import 'package:flutter_networking/dio/http_request.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Networking'),
),
body: Content(),
),
);
}
}
class Content extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 1. HttpClient request
// requestNetworking();
// 2. http request
// httpNetworking();
// 3. dio request
// dioNetworking();
// 4. dio 封装使用
// HTTPRequest.request('https://httpbin.org/get',
// params: {"name": "bmw", 'age': '4'}).then((response) {
// print('dio-封装使用: data: ${response.data}, \nresponse: $response');
// });
return Container(
alignment: Alignment(0.9, 0.95),
child: FloatingActionButton(
child: Text('Float'),
onPressed: () => loadData(),
),
);
}
void loadData() async {
await HTTPRequest.request('/post',
method: 'post', params: {"name": "bmw", 'age': '4'}).then((response) {
print('dio-封装使用: response: $response');
});
}
}
/*
response: {
args: {
age: 4,
name: bmw
},
headers: {
Accept-Encoding: gzip,
Content-Length: 0,
Host: httpbin.org,
User-Agent: Dart/2.13(dart: io),
X-Amzn-Trace-Id: Root=1-61010d4a-7e79c42f56f8d1467074df5e
},
origin: 180.168.144.10,
url: https: //httpbin.org/get?name=bmw&age=4
}
*/
6. 封装的缺陷?
- dio对象 会累加拦截、需要dio对象设置单例最好。