Dio:是什么,Flutter 的 HTTP 客户端特性

作者: IT Sectr 发布日期: 2026-03-07 阅读时间: 8 分钟

Dio — 是一个用于 Dart 和 Flutter 的强大 HTTP 客户端,由中国工程师 Wenda Wang 开发。该库提供高级 API,支持拦截器、FormData、文件上传和请求取消。根据 pub.dev, 2025 的数据,Dio 是 Flutter 生态系统中最流行的 HTTP 客户端,在 GitHub 上拥有超过 8000 颗星。

要点

  • Dio — 用于 Dart 和 Flutter 的强大的 HTTP 客户端,带有拦截器和转换器
  • 拦截器 — 拦截请求、响应和错误的机制,用于日志记录和授权
  • FormData — 内置支持 multipart/form-data 用于文件上传
  • 请求取消 — CancelToken 允许随时中断正在执行的请求
  • 转换器 — 在发送前和接收后对数据进行自定义转换

什么是 Dio?

Dio — 是一个用于 Dart 语言的强大 HTTP 客户端库,最广泛地用于 Flutter 应用程序。Dio 提供丰富的 API,支持拦截器、全局配置、转换器、FormData、文件上传和灵活的超时管理,使其成为 Flutter 社区中网络通信的主要选择。

该库由 Wenda Wang 于 2018 年创建,作为内置 dart:io HttpClient 的替代方案,后者缺乏许多现代功能:所有请求的统一配置、拦截器和自动序列化。到 2025 年,Dio 在流行度上已经超过了 Dart 团队的 http 包,根据 pub.dev 的数据,在 Flutter 生态系统的 HTTP 客户端中占据首位

Dio 支持三种适配器:DartNativeAdapter(Android、iOS、Desktop 上的默认设置)、BrowserAdapter(Web 上)和 IOAdapter。适配器会根据平台自动选择。Dio 还为所有 Flutter 平台提供统一接口 — Android、iOS、Web、macOS、Windows 和 Linux。

Dio 如何工作

Dio 的架构建立在处理器链(handler chain)之上。每个请求都经过一系列拦截器,这些拦截器可以修改请求(InterceptorsWrapper.onRequest)、响应(onResponse)或处理错误(onError)。在拦截器之后,请求到达转换器(Transformer),在发送前转换数据。

Dio 实例通过 BaseOptions 对象进行配置,该对象包含基础 URL、默认标头、超时时间、响应类型(JSON、stream、plain)、查询参数和数据格式。这些设置适用于所有请求,但可以在特定请求中被覆盖。BaseOptions 为整个应用程序提供统一的配置点,简化了 API 端点的更改或全局标头的添加。

Dio 中的每个请求都返回 Response<T>,其中 T — 是经过转换器处理后的数据类型。默认情况下,Dio 会自动将 JSON 响应转换为 Map<String, dynamic>。对于类型化响应,Dio 与序列化包一起使用:json_serializable、freezed 或 built_value。Response 包含 data、headers、statusCode、requestOptions 和附加数据。

Dio 的全局配置

基本配置通过 Dio(BaseOptions) 创建。可以为所有请求设置 baseUrl、connectTimeout 和 receiveTimeout、content-type 和 accept 标头,以及 queryParameters。所有这些参数都应用于每个请求,从而消除了代码重复并集中了网络设置的管理。

Dio 支持两种序列化模式:默认 JSON(responseType: ResponseType.json)和流式(ResponseType.stream)。在流式模式下,Response.data 返回一个可以分部分读取的 ResponseBody。这对于大型有效负载文件很方便,当不希望完全加载到内存中时。Plain 模式返回原始字符串,无需自动 JSON 解析。

Dio 拦截器

拦截器 — Dio 用于拦截和修改请求、响应和错误的关键机制。它们完全取代了 OkHttp 的 Interceptor 和 Ktor 的插件,但具有 Dart 特定的 API 和通过 Future 实现的异步支持。拦截器既可以添加到 Dio 的全局配置中,也可以添加到单个请求中。

拦截器方法用途使用示例
onRequest在发送前修改请求添加授权令牌
onResponse处理成功响应将数据转换为 DTO 对象
onError处理请求错误在 503 时自动重试

LogInterceptor

内置的 LogInterceptor 记录每个请求:方法、URL、标头、正文和执行时间。它有两种模式:compact(每个请求一行)和 full(包含正文的完整信息)。LogInterceptor 在开发过程中特别有用,但建议通过条件导入或全局标志在发布版本中禁用它。

自定义拦截器通过 InterceptorsWrapper 类创建。可以重写一个、两个或全部三个方法(onRequest、onResponse、onError)。Dio 严格按照拦截器添加到 interceptors 列表的顺序执行它们。如果拦截器不调用 handler.next(),则链会中断,响应/错误不会到达应用程序。

在 Dio 中进行身份验证时,使用一个将 Bearer 令牌添加到 Authorization 标头的拦截器。如果服务器返回 401,拦截器在 onError 中尝试通过刷新请求更新令牌,并使用新令牌重复原始请求。这种模式称为令牌刷新拦截器,通过 DioException 实现,检查 response?.statusCode == 401。

Dio 通过 dio_smart_retry 包或自定义的 RetryInterceptor 提供内置的重试逻辑支持。重试对于移动应用程序很重要:当连接断开 2–3 秒时,Dio 会抛出类型为 connectionTimeout 或 connectionError 的 DioException。RetryInterceptor 捕获此异常并以指数延迟(1s、2s、4s)重试请求最多 3 次,从而提高了应用程序在不稳定网络条件下的可靠性。

Dio 在 Dart 中的代码示例

让我们看一下通过 Dio 的基本 GET 请求。使用 BaseOptions 创建实例,设置基础 URL 和超时。请求通过 get() 方法执行,返回带有 Map 格式数据的 Response。

dart
final dio = Dio(BaseOptions(
    baseUrl: 'https://api.github.com',
    connectTimeout: Duration(seconds: 15),
    receiveTimeout: Duration(seconds: 15),
    headers: {
        'Accept': 'application/vnd.github.v3+json',
    },
))

final response = await dio.get('/users/octocat')
print(response.data['登录'])

对于带有 JSON 正文的 POST 请求,传递一个 Map 对象或自定义 DTO。Dio 通过 jsonEncode 自动将 Map 序列化为 JSON。对于类型化的 DTO,使用 queryParameters 选项、data 字段或自定义 Transformer。

dart
final data = {
    'name': 'my-project',
    'description': 'Created via Dio',
    'private': false,
}

final response = await dio.post(
    '/user/repos',
    data: data,
    options: Options(
        contentType: ContentType.json.value,
    ),
)

print(response.data['id'])

添加授权拦截器

自定义拦截器为每个请求添加 Bearer 令牌。onRequest 方法在发送前触发,修改标头。在 401 响应时,拦截器可以刷新令牌并通过 dio.fetch(requestOptions) 方法重复请求。

dart
class AuthInterceptor extends InterceptorsWrapper {
    final String token

    AuthInterceptor(this.token)

    @override
    void onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
    ) {
        options.headers['Authorization'] = 'Bearer $token'
        handler.next(options)
    }
}

dio.interceptors.add(AuthInterceptor('ghp_abc123'))

通过 Dio 上传和下载文件

Dio 简化了通过 FormData 上传文件。要发送文件,从 File、Bytes 或 AssetBundle 创建 MultipartFile。FormData 自动设置 multipart/form-data 标头,具有正确的边界和编码。Dio 通过 onSendProgress 支持上传进度。

对于文件下载,使用 download() 方法,将数据流直接保存到文件。Dio 通过 Range 标头支持断点续传(resume),这对大文件特别有用。下载进度通过 onReceiveProgress 跟踪,允许在 UI 中显示进度条。

dart
final formData = FormData.fromMap({
    'file': await MultipartFile.fromFile(
        '/path/to/photo.jpg',
        filename: 'photo.jpg',
    ),
    'description': 'Profile photo',
})

await dio.post(
    '/upload',
    data: formData,
    onSendProgress: (sent, total) {
        final progress = sent / total * 100
        print('上传:$progress%')
    },
)

// 下载文件
await dio.download(
    'https://example.com/file.zip',
    '/storage/emulated/0/Download/file.zip',
    onReceiveProgress: (received, total) {
        print('下载:${received / total * 100}%')
    },
)

使用 Dio 时的常见错误

错误的错误处理 — 最常见的问题。Dio 在任何问题时都会抛出 DioException(以前是 DioError):无网络、超时、HTTP 4xx/5xx 错误。许多开发人员只捕获通用的 Exception,丢失了有关错误类型及其自定义处理可能性的信息。使用 DioException.type 来确定故障原因。

忽略 CancelToken 会导致请求泄漏。如果用户离开屏幕而请求仍在执行,Dio 会消耗资源,并可能尝试更新已销毁的 State。始终为每个请求创建 CancelToken,并在 dispose() 中取消它。CancelToken 会生成类型为 cancel 的 DioException,需要正确处理。

缺乏临时故障的重试逻辑。在移动设备上,网络经常会暂时不可用。实现一个在超时或 503/502 响应时自动重试请求的拦截器。使用 dio_smart_retry 包中的 RetryInterceptor,或编写一个在尝试之间具有指数延迟的自定义拦截器。

常见问题

Dio 与 Dart 的 http 包有何不同?

Dio 提供拦截器、BaseOptions 全局配置、FormData、上传进度和 CancelToken。Dart 团队的 http 包 — 简约,没有拦截器和全局配置。Dio 用于大型项目,http — 用于简单脚本。

如何在 Dio 中序列化 JSON?

Dio 默认通过 jsonDecode 将 JSON 转换为 Map。对于类型化序列化,使用 json_serializable 或 freezed 包。创建一个自定义拦截器,在 onResponse 中通过 fromJson() 将 response.data 转换为 DTO。

如何在 Dio 中取消请求?

创建一个 CancelToken 并将其传递给请求选项。调用 token.cancel() 会中断请求并引发类型为 cancel 的 DioException。CancelToken 支持同时取消多个请求,这对于在离开屏幕时取消所有请求很方便。

Dio 能在所有 Flutter 平台上运行吗?

是的,Dio 在所有六个 Flutter 平台上运行:Android、iOS、Web、macOS、Windows 和 Linux。每个平台都使用自适应 HTTP 客户端:DartNativeAdapter(原生平台)和 BrowserAdapter(Web)。所有平台的统一 API — 是 Dio 在 Flutter 项目中的关键优势。

Dio 如何处理 cookie?

Dio 不会自动管理 cookie。为了支持 cookie,使用 dio_cookie_manager 包与 cookie_jar 一起使用。CookieManager 拦截 Set-Cookie 和 Cookie 标头,并将 cookie 存储在 PersistCookieJar 中,以便在后续对同一域的请求中自动发送。

总结

  • Dio — Flutter 中最流行的 HTTP 客户端,带有拦截器和转换器
  • 拦截器 onRequest、onResponse 和 onError 修改请求和响应
  • FormData 和 MultipartFile 简化了文件上传到服务器
  • CancelToken 正确取消请求以防止内存泄漏
  • BaseOptions 集中管理 URL、标头和超时的配置
  • DioException 包含错误类型,用于详细的故障处理
  • 进度 onSendProgress 和 onReceiveProgress 显示上传状态

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读