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

如何在Flutter中通过带请求体与请求头的POST请求下载PDF文件?

解决Flutter中使用Dio通过POST请求下载PDF并打开的问题

嘿,作为Flutter新手遇到这个问题很正常,我来一步步帮你搞定它!其实Dio的download方法是支持自定义请求方法、请求体和请求头的,只是默认是GET而已,另外文件存储和打开的部分我们可以借助两个常用插件来实现。

步骤1:添加必要的依赖

首先,在你的pubspec.yaml里添加三个依赖:

  • dio:处理网络请求
  • path_provider:获取设备的标准存储路径
  • open_file:打开本地文件
dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0  # 请使用最新版本
  path_provider: ^2.1.2
  open_file: ^3.3.2

执行flutter pub get完成依赖安装。

步骤2:实现带POST请求体的下载逻辑

我们可以通过Dio的download方法的options参数,指定请求方法为POST,同时传入请求体和请求头。另外用path_provider获取内部存储的downloads目录,确保文件存到正确的位置。

完整代码示例:

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:open_file/open_file.dart';

Dio dio = Dio();

Future<APIResponse> downloadAndOpenPdf({required String token}) async {
  try {
    // 1. 获取设备的Downloads目录路径
    Directory? downloadsDir;
    if (Platform.isAndroid) {
      // Android 获取公共下载目录
      downloadsDir = await getExternalStoragePublicDirectory(DirectoryDownloads);
    } else if (Platform.isIOS) {
      // iOS 获取应用内的Documents目录(可按需调整)
      downloadsDir = await getApplicationDocumentsDirectory();
    }
    
    if (downloadsDir == null) {
      throw Exception("无法获取存储目录");
    }

    // 确保目录存在
    await downloadsDir.create(recursive: true);

    // 2. 定义文件保存路径(示例命名为january_2022.pdf)
    String filePath = "${downloadsDir.path}/january_2022.pdf";

    // 3. 使用Dio执行POST下载
    Response response = await dio.download(
      'https://www.example.com/sample/download',
      filePath,
      options: Options(
        method: 'POST', // 指定请求方法为POST
        headers: {
          'Authorization': 'Bearer $token',
        },
      ),
      data: {"month": "January", "year": "2022"}, // 传入POST请求体
      // 可选:添加下载进度监听
      onReceiveProgress: (received, total) {
        if (total != -1) {
          print("下载进度:${(received / total * 100).toStringAsFixed(0)}%");
        }
      },
    );

    if (response.statusCode == 200) {
      // 4. 下载成功后打开文件
      await OpenFile.open(filePath);
      return APIResponse.fromJson(response.data); // 适配你的APIResponse解析逻辑
    } else {
      throw Exception("下载失败,状态码:${response.statusCode}");
    }
  } catch (e) {
    // 处理异常:网络错误、存储权限不足等
    print("下载出错:$e");
    rethrow; // 或根据需求返回错误状态的APIResponse
  }
}

关键细节说明

  • Dio下载方法的自定义配置:通过options.method指定POST请求,data参数直接传入请求体,完全满足你的需求,无需手动处理文件写入逻辑。
  • 跨平台存储路径:path_provider统一了Android和iOS的存储路径获取,避免了手动拼接路径的兼容性问题。注意Android 10+的Scoped Storage机制,如果遇到权限问题,可调整存储路径到应用私有目录,或在AndroidManifest.xml中添加相应权限声明。
  • 本地文件打开:open_file插件会调用系统默认应用打开PDF,无需自己实现文件解析逻辑。

额外注意事项

  • 权限配置:Android需在AndroidManifest.xml中添加READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE(Android 13+可调整为READ_MEDIA_IMAGES等);iOS需在Info.plist中添加文件访问相关权限描述。
  • 异常处理:可根据业务需求优化异常捕获逻辑,比如给用户展示Toast提示下载失败原因。

内容的提问来源于stack exchange,提问作者kl23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:42:32