Flutter 接口请求封装,以及过滤拦截

对flutter的网络请求做一个封装,包含token的获取和cookie的存储,以及一些异常状态的拦截过滤,代码如下:



import 'package:sp_util/sp_util.dart';

import 'package:connectivity/connectivity.dart';

import 'package:fluttertoast/fluttertoast.dart';

import 'package:dio/dio.dart';

import 'package:dio/adapter.dart';

import 'package:dio_cookie_manager/dio_cookie_manager.dart';

import 'package:cookie_jar/cookie_jar.dart';

import 'dart:collection';

import 'config.dart';

///http请求管理类,可单独抽取出来

class HttpRequest {

  static const CONTENT_TYPE_JSON = "application/json;charset=utf-8";

  static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";

  static Map optionParams = {

    "timeoutMs": 15000,

    "token": null,

  };

  static Map urlobj;

  static String _baseUrl = Config.baseUrl;

  static get(url, {param, Map header={}}) async {

    Map headers = new HashMap();

    headers.addAll(header);

    return await request(

        _url + url, param, headers, new Options(method: "GET"));

  }

  static post(url, param, {Map header ={}}) async {

    Map headers = new HashMap();

    headers.addAll(header);

    return await request(

        _url + url,

        param,

        {"Accept": CONTENT_TYPE_JSON, ...headers},

        new Options(method: 'POST'));

  }

  static toastfn(msg) {

    Fluttertoast.showToast(

      msg: msg,

      toastLength: Toast.LENGTH_SHORT,

      gravity: ToastGravity.CENTER,

      timeInSecForIosWeb: 1,

      fontSize: 16.0,

    );

  }

  ///发起网络请求

  ///[ url] 请求url

  ///[ params] 请求参数

  ///[ header] 外加头

  ///[ option] 配置

  static request(url, params, Map header, Options option,

      {noTip = false}) async {

    //没有网络

    var connectivityResult = await (new Connectivity().checkConnectivity());

    if (connectivityResult == ConnectivityResult.none) {

      toastfn('网络异常,请重试!');

      Response errorResponse;

      errorResponse = new Response(statusCode: 444);

      return {'code': 444, 'data': null, 'error': errorResponse};

    }

    Map headers = new HashMap();

    if (header != null) {

      headers.addAll(header);

      if (header['noToken'] == '1') {

        headers['Authorization'] = headers['noToken'] = '';

      } else {

        //授权码

        headers["Authorization"] = getAuthorization();

      }

    } else {

      //授权码

      headers["Authorization"] = getAuthorization();

    }

    if (option == null) {

      option = new Options(method: "get");

    }

    option.headers = headers;

    Dio dio = new Dio();

    ///超时

    dio.options.connectTimeout = 30000;

    var cookieJar = CookieJar();

    dio.interceptors.add(CookieManager(cookieJar));

    // 强行信任

    if (_baseUrl.indexOf('https') != -1) {

      (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =

          (client) {

        client.badCertificateCallback = (cert, host, port) {

          return true;

        };

      };

    }

    // 添加拦截器

    dio.interceptors

        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {

      print("\n================== 请求数据 ==========================");

      print("url = ${options.uri.toString()}");

      print("headers = ${options.headers}");

      print("params = ${options.data}");

    }, onResponse: (Response response) {

      print("\n================== 响应数据 ==========================");

      print("code = ${response.statusCode}");

      print("url = $url");

      print("headers = $headers");

      print("params = $params");

      print("data = ${response.data}");

      if ([401, 402, 405].contains(response.data['code'])) {

        //token失效,调用native方法,退出登录

        logoutfn();

      } else if (response.data['code'] != 1) {

        toastfn(response.data['msg'] ?? '请求错误');

      }

      return response.data;

    }, onError: (DioError e) {

      print("\n================== 错误响应数据 ======================");

      print("url = $url");

      print("headers = $headers");

      print("params = $params");

      print("type = ${e.type}");

      print("message = ${e.message}");

      print("stackTrace = ${e.toString()}");

      if ([

        'Http status error [401]',

        'Http status error [402]',

        'Http status error [405]'

      ].contains(e.message)) {

        //token失效,清缓存,退出

        logoutfn();

      } else {

        toastfn(e.message ?? '未知错误');

      }

    }));

    Response response;

    try {

      response = await dio.request(url, data: params, options: option);

      return response.data;

    } on DioError catch (e) {

      // 请求错误处理

      Response errorResponse;

      if (e.response != null) {

        errorResponse = e.response;

      } else {

        errorResponse = new Response(statusCode: 666, data: null);

      }

      return {'code': 666, 'data': null, 'error': errorResponse};

    }

  }

  ///清除授权

  static clearAuthorization() async {

    SpUtil.remove('token');

    SpUtil.remove('userInfo');

  }

  ///获取授权token

  static getAuthorization() {

    return SpUtil.getString('token');

  }

  ///获取请求头信息

  static getRequestHeader() {

    var _obj = SpUtil.getObject('requestHeader');

    return _obj ?? {};

  }

}

你可能感兴趣的:(Flutter 接口请求封装,以及过滤拦截)