# http **Repository Path**: dxm_code/http ## Basic Information - **Project Name**: http - **Description**: 一个基于Dio插件封装的Flutter网络请求组件 - **Primary Language**: Dart - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-01-16 - **Last Updated**: 2026-07-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HttpUtils [![Dart Version](https://img.shields.io/badge/dart-%3E%3D3.0.0-blue.svg)](https://dart.dev) [![Dio Version](https://img.shields.io/badge/dio-^5.0.0-orange.svg)](https://pub.dev/packages/dio) [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT) > 基于 **Dio** 封装的纯粹、专业的 Dart HTTP 请求库。专为 Flutter 应用设计,只聚焦 HTTP 核心职责。 ### 核心亮点 - **强类型转换** — 泛型 + 自动解析,直接返回强类型 Dart 对象,支持 List 自动转换。 - **并发无感刷新** — 401 并发自动刷新 Token 且安全排队重试,防止死循环。 - **SSE 流式响应** — 支持 Server-Sent Events,适用于 AI 流式对话、实时推送场景。 - **WebSocket 双向通信** — 自动重连、心跳保活,适用于聊天室、实时通知场景。 - **大文件独立通道** — 上传下载不占用业务 API 连接池,彻底解决弱网界面卡顿。 - **国际化错误翻译** — 错误提示不硬编码,支持自定义翻译器注入以支持 i18n。 - **轻量纯净** — 仅依赖 Dio,无网络监听/心跳探测等越界职责,可注入 `deviceLinkState` 自行桥接。 --- ## 详细文档 为便于更全面地查阅,本项目提供了以下两篇细分文档: * [核心操作指南](doc/http_utils_how_to.md) — 常见业务场景的代码配方与接入说明。 * [技术参考手册](doc/http_utils_reference.md) — 完整的公共 API 签名、底层数据结构及错误码对照表。 --- ## 快速入门 ### 1. 注册模型 (仅需一次) 在入口处注册您的数据模型(自动支持单对象 `User` 及列表 `List` 转换): ```dart // 注册转换器 HttpUtils.registerConverter(User.fromJson); ``` ### 2. 创建网络实例 ```dart void main() { final http = HttpUtils( baseUrl: 'https://api.example.com', connectTimeout: 10000, // 10秒连接超时 enableLogging: true, // 开启日志打印 ); runApp(const MyApp()); } ``` ### 3. 发起请求 (无需 try-catch) 所有方法均返回 `ApiResponse`,底层自动拦截异常并翻译为友好中文: ```dart // GET 获取列表 (自动推导为 List) final response = await http.get>('/users'); if (response.isSuccess) { List users = response.data ?? []; print("获取成功: ${users.length} 条数据"); } else { // 自动翻译的错误信息,如 "网络连接失败,请检查网络设置" print("请求失败 (${response.code}): ${response.message}"); } ``` --- ## 核心场景代码配方
1. Token 认证与 401 自动无感刷新 ```dart void setupAuth(HttpUtils http) { http.authEnabled = true; // 1. 设置 Token 获取与刷新逻辑 http.onGetToken = ([bool refresh = false, HttpUtils? client]) async { final prefs = await SharedPreferences.getInstance(); if (refresh) { // 收到 401 后自动调用此分支以刷新 Token final refreshToken = prefs.getString('refresh_token'); final response = await client!.post('/auth/refresh', data: {'refreshToken': refreshToken}, requireAuth: false); if (response.isSuccess) { final newToken = response.data['token']; await prefs.setString('token', newToken); return newToken; } return null; } // 正常请求时获取本地缓存 return prefs.getString('token'); }; // 2. 自定义认证请求头格式 (可选) http.onGenerateAuthToken = (token) => {'Authorization': 'Bearer $token'}; // 3. 实例级登录过期回调 http.onInstanceAuthFailed = () { // 退出登录,清除本地缓存,跳转至登录页 }; } ```
2. 文件上传与下载 使用独立的下载实例,避免下载大文件造成主接口阻塞: ```dart // 单文件上传 + 进度回调 final response = await http.uploadFile( '/upload', filePath: '/path/to/avatar.jpg', fieldName: 'image', onSendProgress: (sent, total) { print('上传进度: ${(sent / total * 100).toStringAsFixed(1)}%'); }, ); // 文件下载 final downloadResponse = await http.downloadFile( 'https://example.com/file.zip', '/local/path/save.zip', onReceiveProgress: (received, total) { print('下载进度: ${(received / total * 100).toStringAsFixed(1)}%'); }, ); ```
3. 多实例隔离 直接创建多个 `HttpUtils` 实例即可隔离配置与 Token 状态: ```dart // 初始化独立的支付实例 final payHttp = HttpUtils( baseUrl: 'https://pay.example.com', enableAuth: true, ); // 使用 final response = await payHttp.post('/execute', data: {'orderId': '123'}); ```
4. 自定义业务成功判定与数据字段 对接非标准 API 时,可自定义判定逻辑和数据提取字段: ```dart // 对接旧系统:code=0 才算成功,数据在 result 字段中 final legacyHttp = HttpUtils( baseUrl: 'https://legacy.example.com', enableAuth: false, // 自定义成功判定:body.code == 0 successChecker: (body) => body['code'] == 0, // 自定义数据字段提取顺序 dataKeys: ['result', 'data'], ); // 使用 final resp = await legacyHttp.get('/getUser'); if (resp.isSuccess) { // 自动从 result 字段提取数据 print(resp.data); } // 默认支持的字段:data, list, info, result, items, records // 可通过 dataKeys 自定义顺序或缩减 ```
5. SSE 流式响应 (AI 对话/实时推送) ```dart final sse = http.createSse( '/chat/stream', requireAuth: true, data: {'prompt': '你好'}, method: 'POST', ); sse.connect().listen((event) { // event.data — 文本数据 // event.json — 自动解析的 JSON 对象 // event.event — 事件类型 // event.id — 事件 ID(用于断线重连) print('收到: ${event.data}'); }, onError: (e) { print('错误: $e'); }, onDone: () { print('流结束'); }); // 结束时 sse.close(); ```
6. WebSocket 双向通信 (聊天室/实时通知) ```dart final ws = http.createWebSocket( 'wss://api.example.com/chat', heartbeatInterval: Duration(seconds: 30), ); // 监听消息 ws.onMessage.listen((msg) { print('收到: ${msg.text}'); // msg.json — 自动解析的 JSON 对象 }); // 监听连接状态 ws.onStateChange.listen((state) { print('状态: $state'); }); // 连接 ws.connect(); // 发送消息 ws.sendText('hello'); ws.sendJson({'type': 'message', 'content': '你好'}); // 断开 ws.dispose(); ```
--- ## 网络拦截 为防止设备断网导致的 UI 长时间无响应,HttpUtils 在请求发出前会检测 `deviceLinkState`: ``` [ 发起请求 ] │ ▼ 【 deviceLinkState 检测 】 ─── [无网] ───► 返回 -102 "设备网络未连接" │ [有网] ▼ [ Dio 发起真实 HTTP 网络请求 ] ``` 默认 `deviceLinkState` 恒返回 `true`(不检测)。调用方可注入自定义判定逻辑: ```dart // 桥接 connectivity_plus 等第三方网络监听 http.deviceLinkState = () => hasActiveNetwork; ``` > 也可通过 `cancelAllRequests()` 手动取消当前实例所有在途请求。 --- ## API & 错误码简表
点击展开:系统内置错误码对照表 | 错误码 | 错误信息 | 触发场景 | | :-------: | :------------------------------------------------------------------ | :------------------------------------------ | | `-100` | "BaseUrl 未设置,请先调用 setBaseUrl() 方法设置接口地址" | 未初始化即发送请求 | | `-102` | "设备网络未连接" | 客户端未连网(通过 `deviceLinkState` 拦截) | | `-103` | "请求已取消" / "HttpUtils 实例已销毁" | 请求被取消、实例被释放 | | `-2` | "数据解析格式错误: [原因]" | 后端 JSON 结构与 Model 的 fromJson 冲突 | | `4xx/5xx` | 优先返回服务端 body 中 `message`/`msg` 字段,若不存在则使用内置翻译 | 服务端返回错误时自动提取业务错误信息 |
点击展开:HttpUtils 实例可配置 API 清单 #### 构造方法及属性说明: - `HttpUtils(baseUrl: ..., ...)` — 直接构造实例。 - `errorTranslator` — 错误消息翻译器,注入后可实现网络库国际化。 - `authEnabled` — `bool` 可读写,控制实例是否开启 Token 头注入及 401 自动刷新。 - `setBaseUrl(url)` — 动态更改接口地址。 - `dispose()` — 销毁实例,关闭 Dio 连接池。 #### 配置项: | 配置项 | 类型 | 说明 | | :----------------------- | :------------------------ | :------------------------------------------------------------------------------------------------------------------ | | `successChecker` | `bool Function(Map body)` | 自定义业务成功判定逻辑。默认:`code==200 \|\| status==200 \|\| success==true`。适用于非标准返回格式的旧系统。 | | `dataKeys` | `List` | 数据字段提取优先级列表。默认:`[data, list, info, result, items, records]`。按顺序扫描返回 body,匹配即提取。 | | `onInstanceAuthFailed` | `void Function()` | 实例级 Token 认证失败回调,当 Token 刷新失败时触发,用于执行登出、清理缓存等操作。 | | `cancelAllRequests()` | 实例方法 | 取消当前实例所有在途请求。 | | `head()` | 请求方法 | HEAD 请求,与 GET/POST/PUT/DELETE/PATCH 签名一致,常用于健康检查。 |