Nealyang/PersonalBlog

网络请求

Nealyang opened this issue · 4 comments

前言

无论对于一个什么app或者项目、应用来说,网络请求都是必不可少的,从前端的角度而言,有很多的网络请求库,比如 axios,fetch等,当然,也有ajax等等。对于flutter、dart而言,也是同样,下面,就让我们来看下在flutter中,我们如何进行网络请求。

Dart中的网络请求

http.dart 包

从dart原生的角度而言,它是提供了请求包的,package:http/http.dart 当然,也是非常的好用,我们完全可以将它封装下get和post然后使用

      import 'dart:async';
      import 'package:http/http.dart' as http;
      
      class NetUtils {
        // 参数拼接到url后面
        static Future<String> get(String url, {Map<String, String> params}) async {
          if (params != null && params.isNotEmpty) {
            // 如果参数不为空,则将参数拼接到URL后面
            StringBuffer sb = new StringBuffer("?");
            params.forEach((key, value) {
              sb.write("$key" + "=" + "$value" + "&");
            });
            String paramStr = sb.toString();
            paramStr = paramStr.substring(0, paramStr.length - 1);
            url += paramStr;
          }
          http.Response res = await http.get(url);
          return res.body;
        }
      
        // post请求
        static Future<String> post(String url, {Map<String, String> params}) async {
          http.Response res = await http.post(url, body: params);
          return res.body;
        }
      }

如上,我们就完成了对请求的封装,后面我们只需要在我们需要的地方使用post、get即可。

但是在这个项目中,我更倾向于使用dio ,他还有中文文档哦。
关键他已经帮我们封装了基本请求,不仅如此,还有拦截器、代理、cookie等。基本已经很全很方便了。

引入dio

首先在 pubspec.yaml 入驻相关包,这里不再赘述。在lib/util/文件夹下新建net_utils.dart文件用于封装一些请求方法

  • lib/util/net_utils.dart
      import 'package:dio/dio.dart';
      import 'dart:async';
      
      var dio = new Dio();
      
      class NetUtils {
        
        static Future get(String url,{Map<String,dynamic> params}) async{
           var response = await dio.get(url, data: params);
          return  response.data;
        }
      
        static Future post(String url,Map<String,dynamic> params) async{
          var response = await dio.post(url, data: params);
          return response.data;
        }
      }

还记得我们之前的约束嘛,index_page只想通过一个方法,拿到需要的数据,不要有太多累赘的数据处理,所以这里我们需要修改之前我们处理本地json中的方法

  • lib/util/data_utils.dart
    // 首页列表数据
    static Future<List<IndexCell>> getIndexListData(
        Map<String, dynamic> params) async {
      var response = await NetUtils.get(Api.RANK_LIST, params: params);
      var responseList = response['d']['entrylist'];
      List<IndexCell> resultList = new List();
      for (int i = 0; i < responseList.length; i++) {
        IndexCell cellData = new IndexCell.fromJson(responseList[i]);
        resultList.add(cellData);
      }
  
      return resultList;
    }

对于Api.RANK_LISK大家可以点击这里查看

至此,我们的准备工作就做好了,下面就来愉快使用这个方法吧。

  • lib/pages/index_page.dart
  const pageIndexArray = Constants.RANK_BEFORE;
...
  int _pageIndex = 0;
   
  getList(bool isLoadMore) {
    if(!isLoadMore){
      // reload的时候重置page
      _pageIndex = 0;
    }
    _params['before'] = pageIndexArray[_pageIndex];

    DataUtils.getIndexListData(_params).then((result) {
     setState(() {
        _listData = result;
      });
    });
  }

isLoadMore 从命名上即可看出,是判断是否为翻页,Constants.RANK_BEFORE 是我从web版掘金中,摘的几个翻页,这里不是pageNum为1、2、3 。。。翻页的,具体逻辑没有去思考,倒是这里我们只需要做成翻页即可。 私有变量 int _pageIndex = 0; 即为我们的page.

最后在页面初始化的时候,开始第一次的网络请求

  @override
  void initState() {
    super.initState();
    getList(false);
  }

现在,我们的数据就已经是线上的了。

img

总结

至此,我们完成了网络请求,并且已经封装了后面翻页的请求方法。你应该学会

  • Dart中的基础网络请求
  • dio的使用

你好,dio最新版本2.1.2版本,查询参数传递,变成queryParameters: params

你好,dio最新版本2.1.2版本,查询参数传递,变成queryParameters: params

demo 写好后的确没有追新版本,欢迎提 pr 哇

zzmkj commented

// 首页list
static const String RANK_LIST = 'https://timeline-merger-ms.juejin.im/v1/get_entry_by_rank';

首页数据请求服务好像访问不了。

开放的api在哪里查找呢,现在有些接口已经访问不同了,无法往下进行
比如这章使用的static const String RANK_LIST = 'https://timeline-merger-ms.juejin.im/v1/get_entry_by_rank';