[Flutter] 06-Flutter的网络请求

我们项目中展示的大部分数据都是来自服务器,我们需要向服务器请求数据,并且对他们进行解析展示。向服务器发出请求就需要用到网络请求相关的知识。

一. 网络请求的方式

在Flutter中常见的网络请求方式有三种:HttpClient、http库、dio库;

1.1. HttpClient

HttpClient是dart自带的请求类,在io包中,实现了基本的网络请求相关的操作。
需要导入httpClient包,import 'dart:convert'; 和 import 'dart:io' ;

网络调用通常遵循如下步骤:

  1. 创建 client.
  2. 构造 Uri.
  3. 发起请求, 等待请求,同时您也可以配置请求headers、 body。
  4. 关闭请求, 等待响应.
  5. 解码响应的内容.

网络请求实例:

import 'dart:convert';
import 'dart:io';

main(List<String> args) {
  requestNetwork();
}

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("");

  // 3.打印请求结果
  if (response.statusCode == HttpStatus.ok) {
    print(response.data);
  } else {
    print("请求失败:${response.statusCode}");
  }
}

1.4. dio库的封装

http_config.dart

class HTTPConfig {
  static const baseURL = "https://httpbin.org";
  static const timeout = 5000;
}

http_request.dart

import 'package:dio/dio.dart';
import 'package:testflutter001/service/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.在进行任何网络请求的时候, 可以添加一个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": "tao", 'age': 18}).then((res) {
  print(res);
});

HttpRequest.request("https://httpbin.org/post",
                    method: "post", params: {"name": "tao", 'age': 18}).then((res) {
  print(res);
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345