Flutter的网络请求

1,104 阅读3分钟

flutter网络请求库

在FLutter中,我们通常使用dio来进行网络请求。

  1. dio的安装
dio: ^3.0.10 # 网络请求

如此安装好后执行pub get 那么我们就可以使用它啦。

  1. dio的简单封装

我们都知道,要想使用一个框架,仅仅引入进来是不够的还需要我们去进行简单的封装,以便可以在项目中方便的使用

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

import 'package:dio/dio.dart';
import 'package:dio/adapter.dart';
import 'package:kooielts/base/base_resp.dart';
import 'package:kooielts/base/utils.dart';
import '../config.dart';
import 'encrypt_params.dart';

class HttpManager {
  Dio _dio;
  BaseOptions _options;
  static const int _receiveTimeout = 5000;
  static const int _sendTimeout = 5000;
  static const int _connectTimeout = 5000;

  Future post<T>(String path, Map params) async {
    //params["app_id"] = Config.getInstance().APP_ID;
    print("path:$path");
    print("params$params");
    //params["validation"] = FlutterNoCppSrc.getNetParams(json.encode(params));
    var response = await _dio.post(path, data: params);
    if (response.statusCode == HttpStatus.ok) {
      return response.data["obj"];
    }
    return new Future.error(new DioError(
        request: response.request,
        response: response,
        type: DioErrorType.RESPONSE,
        error: "请求失败"));
  }

  static BaseOptions _getDefOptions() {
    return BaseOptions(
      connectTimeout: _connectTimeout,
      receiveTimeout: _receiveTimeout,
      sendTimeout: _sendTimeout,
      headers: Utils.getHeader(),
      baseUrl: Config.getInstance().API_DOMAIN,
      contentType:
          ContentType.parse("application/x-www-form-urlencoded").toString(),
    );
  }

  // 单例对象
  static HttpManager _instance = HttpManager._internal();

  // 内部构造方法,可避免外部暴露构造函数,进行实例化
  HttpManager._internal() {
    _options = _getDefOptions();
    _dio = Dio(_options);
    // 设置代理 便于本地 charles 抓包
    (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
        (HttpClient client) {
      client.findProxy = (uri) {
        return "PROXY 10.155.43.118:8888";
      };
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) {
        return true;
      };
    };
  }

  // 工厂构造方法,这里使用命名构造函数方式进行声明
  factory HttpManager.getInstance() => _instance;
}

此处我们封装了一个网络请求类,以后我们用此类就可以愉快地进行网络请求了。 注:HttpManager 是单例类。我们在外界只需要调用getInstance就能拿到这个类的对象了。此单例类在_internal私有构造方法中初始化了dio及其他的一些网络配置,我们只需要在外面调用此类的post方法即可进行网络请求。在post(String path, Map params)方法中path是请求的url地址,params是请求参数。同时我们可以在此方法内给params参数增加公共请求。

  1. 网络模块的基本结构 我们在开发一个app时,不只是要把网络请求发送出去,把结果拿回来而已,同时还需要进行其他的一些配置。此时我们需要搭建一个基本的结构。下面图片是我自己写的一个简单结构的结构图

image.png

从图中我们可以看出

  • api.dart 一个可以简单配置请求地址的dart类,我们可以在此类中配置baseUrl后面的url请求地址。
import '../config.dart';

class Api{
  static const String launchInfo = "/api/XXX/web/courses/coursesTypeList";

}
  • http_manager.dart 刚才上面说到的http管理类。

  • config.dart 一个专门根据不同的环境,比如说内部环境和外网环境来进行各项配置的单例类。比如说根据内外网环境不同配置不同的baseUrl和appID等等等等。。。。

import 'env.dart';

class Config {
  //各种配置
  String APP_ID;
  String SECURITY_KEY;
  String API_DOMAIN;

  // 内网环境
  static final String _NEIBU_APP_ID = "001";
  static final String _NEIBU_SECURITY_KEY = "c5d1c2f4ae7c4c3ba705e6002d51bd92";
  static final String _NEIBU_API_DOMAIN = "https://mobi.neibu.ku.com";
  // 外网环境
  static final String _PRODUCT_APP_ID = "002";
  static final String _PRODUCT_SECURITY_KEY = "d88b5b5d293d418abac9b0627b0ab5a8";
  static final String _PRODUCT_API_DOMAIN = "https://mobi.ku.com";
  void setEnv(Env env){
    switch (env) {
      case Env.NEIBU:
        APP_ID=_NEIBU_APP_ID;
        SECURITY_KEY=_NEIBU_SECURITY_KEY;
        API_DOMAIN=_NEIBU_API_DOMAIN;
        break;
      case Env.PRODUCT:
        APP_ID=_PRODUCT_APP_ID;
        SECURITY_KEY=_PRODUCT_SECURITY_KEY;
        API_DOMAIN=_PRODUCT_API_DOMAIN;
        break;
      default:
        APP_ID=_PRODUCT_APP_ID;
        SECURITY_KEY=_PRODUCT_SECURITY_KEY;
        API_DOMAIN=_PRODUCT_API_DOMAIN;
        break;
    }
  }


  // 单例对象
  static final Config _instance=Config._internal();
  // 内部构造方法,可避免外部暴露构造函数,进行实例化
  Config._internal();
  // 工厂构造方法,这里使用命名构造函数方式进行声明
  factory Config.getInstance() => _instance;
}
  • env.dart 一个标识环境的枚举类
enum Env {
  NEIBU,
  PRODUCT
}
  • Utils.dart 一个设置公共请求头的类
import 'package:fluttertoast/fluttertoast.dart';
class Utils{
  static Map<String,String> getHeader(){
    try {
      return {
      "screensize":"1080*2460",
      "curAppid":"381",
      "channel":"guanfang",
      "User-Agent":"Mozilla/5.0 (Linux; Android 10; V1836A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36",
      "version":"3.3.0",
      "vcode":"330",
      "macaddr":"02:00:00:00:00:00",
    "platform":"android_phone_10",
    "pversion":"1.1",
    "appname":"itspro",
    "vendor":"itspro",
    "imei":"3bc5003ba2ab47c0",
    "model":"vivo,V1836A",
    "Content-Type":"application/x-www-form-urlencoded",
    "Content-Length":"61",
    "Host":"mobi.neibu.ku.com",
    "Connection":"Keep-Alive",
    "Accept-Encoding":"gzip",
      };
    } catch (exception) {
      toast(exception.toString());
    }
  }

  //static toast(String message) {
    //Fluttertoast.showToast(
      //msg: message,
      //toastLength: Toast.LENGTH_SHORT,
      //gravity: ToastGravity.CENTER,
    //);
  //}
}

通过以上配置,我们就可以在dart中进行愉快地网络请求了。