flutter 网络请求的几种常见方式

1,883 阅读2分钟

前言

各位同学大家好,有段时间没有给大家更新文章 ,具体多久我记不清楚了。今天有时间给大家简单讲解下flutter的里面网络编程部分 也就flutter里面处理网络请求的几个点 flutter里面可以使用 原生的httpclient 或者是 http的库还有dio的库 我们今天就分开讲解,那份废话不多说我们正式开始 。

准备工作 :

需要安装flutter的开发环境:大家可以去看看之前的教程: 1 win系统flutter开发环境安装教程: 

www.jianshu.com/p/152447bc8…

2 mac系统flutter开发环境安装教程:

www.jianshu.com/p/bad2c35b4…

需要用到的三方库

  http: ^0.12.0 #latest version
  dio: ^3.0.1

请在pubspec.yaml 文件中添加依赖 image.png 然后在控制台执行flutter pub get命令下载依赖即可

使用原生的httpclient请求

  _getIPAddress() async {
    var url = 'https://httpbin.org/ip';
    var testUrl="http://192.168.9.103:8090/boss/position/getpositioninfo";
    var httpClient = new HttpClient();
    String result;
    try {
      var request = await httpClient.getUrl(Uri.parse(testUrl));
      var response = await request.close();
      if (response.statusCode == HttpStatus.OK) {
        var json = await response.transform(utf8.decoder).join();
        var data = jsonDecode(json);

        print(data.toString());
        result=data.toString();

        //result = data['origin'];
      //  print("result --- > "+result);

      } else {
        result =
        'Error getting IP address:\nHttp status ${response.statusCode}';
      }
    } catch (exception) {
      result = 'Failed getting IP address';
    }
    // If the widget was removed from the tree while the message was in flight,
    // we want to discard the reply rather than calling setState to update our
    // non-existent appearance.
    if (!mounted) return;
    setState(() {
      getStr = result;
    });
  }

测试效果
image.png image.png

使用http 库请求

  • get请求

  var data;
  _fetchGet() async {
    Map newTitle;
    final response =
    await http.get('https://jsonplaceholder.typicode.com/posts/1');
    final responseJson = json.decode(response.body);
    print("请求成功 ---------- "+responseJson.toString());
    newTitle = responseJson;

    setState(() {
      data = newTitle['title'];
      print("title====" + data);
      str=responseJson.toString();
    });
  }

http 库只需要在异步方法里面调用http.get方法然后传入url即可 然后通过json.decode讲返回数据转成map进行解析 我们这边请求是不带参数 如果有参数则只需要动态拼接在url的后面即可

测试效果

image.png image.png

  • post请求

void _httpPost() async {
    //头部
    var headers = Map<String, String>();
    headers["loginSource"] = "IOS";
    headers["useVersion"] = "3.1.0";
    headers["isEncoded"] = "1";
    headers["bundleId"] = "com.nongfadai.iospro";
    headers["loginSource"] = "IOS";
    headers["Content-Type"] = "application/json";
    //参数
    Map params = {'v': '1.0','month':'7','day':'25','key':'bd6e35a2691ae5bb8425c8631e475c2a'};
    // 嵌套两层都可以,但是具体哪个好还有待确认????
    var jsonParams = utf8.encode(json.encode(params));
    // var jsonParams = json.encode(params);
    var httpClient = http.Client();
    var uri = Uri.parse("http://api.juheapi.com/japi/toh");
    http.Response response =
    await httpClient.post(uri, body: jsonParams, headers: headers);

    if (response.statusCode == HttpStatus.ok) {
      print('请求成功');
      print(response.headers);//打印头部信息
      print("post------${response.body}");
      setState(() {
          str=response.body.toString();
      });
    } else {
      print('请求失败 code 码${response.statusCode}');
  }
}

post请求我们实例化httpClient 对象 然后调用 httpClient.post 方法传入URL 和参数 url是调用 Uri.parse 传入 参数通过body传到服务端

测试效果

image.png image.png

使用dio处理网络请求

  • 简单dio get 请求示例

  dioGet()async{
    var url="http://192.168.9.103:8090/boss/position/getpositioninfo" ;
     Dio  dio=new  Dio();
     Response response=await dio.get(url);
     setState(() {
       str=response.data.toString();
     });
     print(response.data.toString());
    }

  • 简单dio post请求示例

dioPosy()async{
    var url="http://192.168.9.103:8090/boss/position/getpositioninfo" ;
    Dio  dio=new  Dio();
    Response response=await dio.post(url);
    setState(() {
      str=response.data.toString();
    });
    print(response.data.toString());
  }
  • 发起多个并发请求:

response = await Future.wait([dio.post('/info'), dio.get('/token')]);
  • 下载文件:

response = await dio.download('https://www.google.com/', './xx.html');
  • 以流的方式接收响应数据:

Response<ResponseBody> rs;
rs = await Dio().get<ResponseBody>(url,
  options: Options(responseType: ResponseType.stream),  //设置接收类型为stream
);
print(rs.data.stream); //响应流
  • 以二进制数组的方式接收响应数据:

Response<List<int>> rs 
rs = await Dio().get<List<int>>(url,
 options: Options(responseType: ResponseType.bytes), //设置接收类型为二进制数组
);
print(rs.data); // 二进制数组
  • 发送 FormData:

var formData = FormData.fromMap({
  'name': 'wendux',
  'age': 25,
});
var response = await dio.post('/info', data: formData);
  • 通过FormData上传多个文件:

var formData = FormData.fromMap({
  'name': 'wendux',
  'age': 25,
  'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'),
  'files': [
    await MultipartFile.fromFile('./text1.txt', filename: 'text1.txt'),
    await MultipartFile.fromFile('./text2.txt', filename: 'text2.txt'),
  ]
});
var response = await dio.post('/info', data: formData);
  • 监听发送(上传)数据进度:

response = await dio.post(
  'http://www.dtworkroom.com/doris/1/2.0.0/test',
  data: {'aa': 'bb' * 22},
  onSendProgress: (int sent, int total) {
    print('$sent $total');
  },
);

List<int> postData = <int>[...];
await dio.post(
  url,
  data: Stream.fromIterable(postData.map((e) => [e])), //创建一个Stream<List<int>>
  options: Options(
    headers: {
      Headers.contentLengthHeader: postData.length, // 设置content-length
    },
  ),
);
// 二进制数据
List<int> postData = <int>[...];
await dio.post(
  url,
  data: Stream.fromIterable(postData.map((e) => [e])), //创建一个Stream<List<int>>
  options: Options(
    headers: {
      Headers.contentLengthHeader: postData.length, // 设置content-length
    },
  ),
);

测试效果

image.png

更多详细dio使用示例 请看 github.com/flutterchin… 有详细的说明我就不展开讲了

最后总结

flutter里面的网络编程方式有很多目前主流就是使用dio库和http 但是我这边还是要附带讲一下原生httpclient 因为dio也是基于httpclient封装的 所以我们有必要了解其实现过程,然后就是dio库的各种用法 因为库本身功能很强也我这边篇幅有限就不展开讲 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦