You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter 通用API调用类/方法(GET/POST等)实现示例咨询

Flutter 通用API请求封装实现示例

我们通常基于dio网络库实现通用请求封装,以下是可直接复用的实现方案,支持统一异常拦截、统一请求头注入、GET/POST/PUT/DELETE等全请求类型适配:

第一步:添加依赖

在pubspec.yaml中引入dio依赖:

dependencies:
  dio: ^5.4.0 # 可替换为最新稳定版

第二步:通用请求类实现

import 'package:dio/dio.dart';

class ApiClient {
  // 单例实例,避免重复初始化
  static final ApiClient _instance = ApiClient._internal();
  factory ApiClient() => _instance;
  ApiClient._internal() {
    _initDio();
  }

  late final Dio _dio;
  final String _baseUrl = 'https://你的API基础地址/';

  // 初始化基础配置
  void _initDio() {
    _dio = Dio(BaseOptions(
      baseUrl: _baseUrl,
      connectTimeout: const Duration(seconds: 15),
      receiveTimeout: const Duration(seconds: 15),
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        // 可在此添加通用固定请求头
      },
    ));

    // 统一拦截器配置
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 统一注入动态请求头,例如用户token
        // String? token = 你的全局token获取逻辑();
        // if (token != null) options.headers['Authorization'] = 'Bearer $token';
        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 统一处理业务状态码,例如token过期跳转登录
        // if (response.data['code'] == 401) {
        //   全局跳转登录页逻辑();
        // }
        return handler.next(response);
      },
      onError: (DioException e, handler) {
        // 统一异常提示,例如网络错误toast弹窗
        // String errorMsg = _handleError(e);
        // 全局toast提示逻辑(errorMsg);
        return handler.next(e);
      },
    ));
  }

  // 通用请求核心方法
  Future<T> request<T>(
    String path, {
    String method = 'GET',
    Map<String, dynamic>? queryParams,
    dynamic data,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    options ??= Options();
    options.method = method;

    try {
      final response = await _dio.request(
        path,
        queryParameters: queryParams,
        data: data,
        options: options,
        cancelToken: cancelToken,
      );
      // 可根据后端返回格式统一解析,直接返回业务数据
      // 示例:后端返回格式为{code:xxx, msg:xxx, data:xxx}时,直接返回data字段
      // return response.data['data'] as T;
      return response.data as T;
    } on DioException catch (e) {
      throw _handleError(e);
    } catch (e) {
      throw '未知错误:${e.toString()}';
    }
  }

  // 异常格式化处理
  String _handleError(DioException e) {
    switch (e.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
        return '网络请求超时,请稍后重试';
      case DioExceptionType.badResponse:
        final statusCode = e.response?.statusCode;
        if (statusCode == 400) return '请求参数错误';
        if (statusCode == 401) return '登录已过期,请重新登录';
        if (statusCode == 403) return '暂无权限访问该资源';
        if (statusCode == 404) return '请求的资源不存在';
        if (statusCode == 500) return '服务器内部错误';
        return '服务器错误,状态码:$statusCode';
      case DioExceptionType.cancel:
        return '请求已取消';
      case DioExceptionType.unknown:
      default:
        return '网络异常,请检查网络设置后重试';
    }
  }

  // 快捷GET请求
  Future<T> get<T>(
    String path, {
    Map<String, dynamic>? queryParams,
    Options? options,
    CancelToken? cancelToken,
  }) =>
      request(
        path,
        method: 'GET',
        queryParams: queryParams,
        options: options,
        cancelToken: cancelToken,
      );

  // 快捷POST请求
  Future<T> post<T>(
    String path, {
    Map<String, dynamic>? queryParams,
    dynamic data,
    Options? options,
    CancelToken? cancelToken,
  }) =>
      request(
        path,
        method: 'POST',
        queryParams: queryParams,
        data: data,
        options: options,
        cancelToken: cancelToken,
      );
  // 可按需求扩展put、delete等快捷方法
}

使用示例

// 示例1:GET请求
void fetchUserInfo() async {
  try {
    final userInfo = await ApiClient().get<Map>(
      '/user/info',
      queryParams: {'userId': 123},
    );
    // 直接处理业务数据
    print('用户信息:$userInfo');
  } catch (e) {
    // 仅需处理业务特殊异常,通用异常已在封装类统一处理
    print('请求失败:$e');
  }
}

// 示例2:POST请求
void submitForm() async {
  try {
    final result = await ApiClient().post<Map>(
      '/form/submit',
      data: {'name': '张三', 'age': 25},
    );
    print('提交结果:$result');
  } catch (e) {
    print('提交失败:$e');
  }
}

内容的提问来源于stack exchange,提问作者CHANDUKA SAMARASINGHE.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:36:03