flutter 网络请求dio的简单使用以及请求头参数的自定义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flutter 网络请求dio的简单使用以及请求头参数的自定义相关的知识,希望对你有一定的参考价值。

参考技术A

dio的使用方式有很多,我就只选出我认为最好用的api方式做下记录,把get成post就是post请求了,网络请求都用的百度的api,实际上的response没有任何意义,所以只要打印出response有值即可。
1.最简单的请求例子,网络请求是异步的所以用async await

2.带有参数的get请求

3.自定义请求头,可定义的请求头dart已经为我们提供了专门的类存了对应的字符,引入以下库,就能使用 HttpHeaders

一般我们请求接收到的数据是json格式,如\'accept: application/json\',我们就可以这样自定义请求头

4.使用Baseoptions

其他详细参数设置参考如下:

Flutter网络请求Dio库的使用及封装

Dart语言内置的HttpClient实现了基本的网络请求相关的操作。但HttpClient本身功能较弱,很多网络请求常用功能都不支持,因此在实际项目中,我们更多是使用dio库实现网络请求。

注:Flutter官网同样推荐在项目中使用Dio库。

Dio文档地址: pub.dev地址:dio | Dart Package

一、项目目录结构

文件夹功能
components放置全局共用组件
router全局路由管理
service管理接口请求并对返回数据进行处理,复杂功能逻辑处理
storeprovider全局状态管理
utile工具类,例如:接口请求工具类,数据持久化工具类,加密解密工具类……
views界面管理,实现界面UI绘制的代码逻辑

二、封装思路:

1、在DioRequest工具类中统一初始化网络请求常见配置,实现请求拦截器、响应拦截器以及错误处理。

2、统一在service中管理接口请求,并且对返回的数据根据实际需求进行处理,如果数据的修改需要更新UI或者需要全局共享该数据,可以结合provider实现。

三、添加依赖

在pubspec.yaml文件中添加所需要的第三方依赖库

dev_dependencies:
  flutter_test:
    sdk: flutter 
  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^1.0.0
  # 数据请求
  dio: ^4.0.4

四、简单实现网络请求

utils目录中新建dio_request.dart文件实现DioRequest网络请求的工具类。

import 'package:dio/dio.dart';

/// 请求方法
enum DioMethod 
  get,
  post,
  put,
  delete,
  patch,
  head,


class DioUtil 
  /// 单例模式
  static DioUtil? _instance;
  factory DioUtil() => _instance ?? DioUtil._internal();
  static DioUtil? get instance => _instance ?? DioUtil._internal();

  /// 连接超时时间
  static const int connectTimeout = 60 * 1000;

  /// 响应超时时间
  static const int receiveTimeout = 60 * 1000;

  /// Dio实例
  static Dio _dio = Dio();

  /// 初始化
  DioUtil._internal() 
    // 初始化基本选项
    BaseOptions options = BaseOptions(
        baseUrl: 'http://127.0.0.1:7001/app/',
        connectTimeout: connectTimeout,
        receiveTimeout: receiveTimeout);
    _instance = this;
    // 初始化dio
    _dio = Dio(options);
    // 添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(
        onRequest: _onRequest, onResponse: _onResponse, onError: _onError));
  

  /// 请求拦截器
  void _onRequest(RequestOptions options, RequestInterceptorHandler handler) 
    // 对非open的接口的请求参数全部增加userId
    if (!options.path.contains("open")) 
      options.queryParameters["userId"] = "xxx";
    
    // 头部添加token
    options.headers["token"] = "xxx";
    // 更多业务需求
    handler.next(options);
    // super.onRequest(options, handler);
  

  /// 相应拦截器
  void _onResponse(
      Response response, ResponseInterceptorHandler handler) async 
    // 请求成功是对数据做基本处理
    if (response.statusCode == 200) 
      // ....
     else 
      // ....
    
    if (response.requestOptions.baseUrl.contains("???????")) 
      // 对某些单独的url返回数据做特殊处理
    
    handler.next(response);
  
  
  /// 错误处理
  void _onError(DioError error, ErrorInterceptorHandler handler) 
    handler.next(error);
  

  /// 请求类
  Future<T> request<T>(
    String path, 
    DioMethod method = DioMethod.get,
    Map<String, dynamic>? params,
    data,
    CancelToken? cancelToken,
    Options? options,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  ) async 
    const _methodValues = 
      DioMethod.get: 'get',
      DioMethod.post: 'post',
      DioMethod.put: 'put',
      DioMethod.delete: 'delete',
      DioMethod.patch: 'patch',
      DioMethod.head: 'head'
    ;
    options ??= Options(method: _methodValues[method]);
    try 
      Response response;
      response = await _dio.request(path,
          data: data,
          queryParameters: params,
          cancelToken: cancelToken,
          options: options,
          onSendProgress: onSendProgress,
          onReceiveProgress: onReceiveProgress);
      return response.data;
     on DioError catch (e) 
      rethrow;
    
  

  /// 开启日志打印
  /// 需要打印日志的接口在接口请求前 DioUtil.instance?.openLog();
  void openLog() 
    _dio.interceptors
        .add(LogInterceptor(responseHeader: false, responseBody: true));
  

五、实现登录注册服务

lib下新建service目录,并在service目录中新建login.dart文件。

import 'package:flutter_dio/utils/dio_util.dart';

class LoginService 
  /// 单例模式
  static LoginService? _instance;
  factory LoginService() => _instance ?? LoginService._internal();
  static LoginService? get instance => _instance ?? LoginService._internal();

  /// 初始化
  LoginService._internal() 
    // 初始化基本选项
  

  /// 获取权限列表
  getUser() async 
    /// 开启日志打印
    DioUtil.instance?.openLog();

    /// 发起网络接口请求
    var result = await DioUtil().request('get_user', method: DioMethod.get);
    return result.data;
  

六、使用service服务

  @override
  void initState() 
    // TODO: implement initState
    super.initState();

    /// 发起网络接口请求
    LoginService().getUser().then((value) => print(value));
  

往期内容:

一、半天时间掌握Dart开发语言-基础学习

二、半天时间掌握Dart开发语言-类的学习

三、【Flutter开发环境搭建】Java SDK安装

四、【Flutter开发环境搭建】Android SDK、Dart SDK及Flutter SDK安装_

五、Flutter路由传参

六、flutter全局状态管理Provider

七、Flutter自定义iconfont字体图标

以上是关于flutter 网络请求dio的简单使用以及请求头参数的自定义的主要内容,如果未能解决你的问题,请参考以下文章

flutter中dio网络get请求使用总结

Flutter网络请求Dio库的使用及封装

Flutter--网络请求dio封装网络请求框架

flutter dio 网络请求问题

Flutter进行HTTP请求并保存登陆状态(dio)

Flutter进行HTTP请求并保存登陆状态(dio)