1.Dio的使用
1.1 在Flutter项目中接入Dio依赖
在Flutter项目中的pubspec.yaml中添加以下依赖,即可使用Dio
为了支持Flutter Web,v3.x被大量重构,因此与3.x版本不兼容。有关更新的详细列表,请参见此处。
1 | dependencies: |
2 | dio: 3.x #latest version |
如果使用的是Android studio编辑器,需要在添加完依赖后,点击Packages get,如果使用VSCode编辑器,添加完文件后,请保存文件,VSCode会自动拉下依赖,如果没有拉下依赖,请在你的项目的根路径下,打开cmd命令行,敲下以下命令
1 | flutter pub get |
注意:在拉取依赖时可能会出现以下问题(命令行一直卡在这个地方)
1 | Running "flutter packages get" in project_name... |
解决:把默认的 package 获取地址改为访问没有问题的镜像站就可以了。
Linux或Mac:
1 | export PUB_HOSTED_URL=https://pub.flutter-io.cn |
2 | export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn |
Windows:
新增两个环境变量即可
1 | 变量名:PUB_HOSTED_URL ===== 变量值:https://pub.flutter-io.cn |
2 | 变量名:FLUTTER_STORAGE_BASE_URL ===== 变量值:https://storage.flutter-io.cn |
不会添加环境变量的自行google
最后在执行一下 flutter doctor -v命令
下载在 package get 应该就没有问题了。
反正我是没问题了。
1.2 简单的使用方法
1 | import 'package:dio/dio.dart'; // 在使用的地方导包 |
2 | void getHttp() async { |
3 | try { |
4 | Response response = await Dio().get("[想要请求的地址]"); |
5 | print(response); |
6 | } catch (e) { |
7 | print(e); |
8 | } |
9 | } |
其他
1.Dio在请求Https(超文本传输安全协定)
1.1 异常打印
1 | HandshakeException: Handshake error in client (OS Error: CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:363)) |
1.2 问题解析
1 | 证书校验不会通过,请求失败。主要原因是: |
2 | 1.ip直连时服务器获取不到host信息,所以不知道应该返回哪个证书,一般返回一个默认证书. |
3 | 2.ip地址肯定不在返回证书的dns 列表中,此步骤必然失败 |
1.3 问题解决(无证书校验)
综上所述,如果非要使用https ip直连,则只能将证书校验忽略,如:
1 | var dio = new Dio(); |
2 | dio.interceptors.add(LogInterceptor(responseBody: true)); |
3 | (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate=(client){ |
4 | client.badCertificateCallback=(X509Certificate cert, String host, int port){ |
5 | // 默认情况下,这个cert证书是网站颁发机构的证书,并不是网站证书,开发者可以验证一下 |
6 | return true; //忽略证书校验 |
7 | }; |
8 | }; |
9 | await dio.get("[https的请求地址]",).then(print); //可以成功 |
但如此一来,https协议的安全策略全部废掉了,这样无法防御通过伪造证书的中间人攻击。
1.3.1 问题解决 (HTTPS证书验证)
有两种验证https证书的方法。假设证书格式为PEM,代码如下:
1 | String PEM="XXXXX"; // certificate content |
2 | (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) { |
3 | client.badCertificateCallback=(X509Certificate cert, String host, int port){ |
4 | if(cert.pem==PEM){ // Verify the certificate |
5 | return true; |
6 | } |
7 | return false; |
8 | }; |
9 | }; |
另一种方法是在创建SecurityContext时创建一个HttpClient
1 | (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) { |
2 | SecurityContext sc = new SecurityContext(); |
3 | //file is the path of certificate |
4 | sc.setTrustedCertificates(file); |
5 | HttpClient httpClient = new HttpClient(context: sc); |
6 | return httpClient; |
7 | }; |
2 第二种异常
2.1 异常打印
1 | DioError [DioErrorType.DEFAULT]: SocketException: OS Error: Connection reset by peer, errno = 104, address = www.easy-mock.com, port = 40652 |
2.2 异常分析
你所请求的地址打不开