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

Flutter使用Dio下载PDF遇HTTP 400错误的排查求助

Flutter中使用Dio下载PDF时出现HTTP 400错误

错误信息

E/flutter (14805): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioError [DioErrorType.response]: Http status error [400]
E/flutter (14805): Source stack:
E/flutter (14805): #0      DioMixin.fetch (package:dio/src/dio_mixin.dart:488:35)
E/flutter (14805): #1      DioMixin.request (package:dio/src/dio_mixin.dart:483:12)
E/flutter (14805): #2      DioForNative.download (package:dio/src/entry/dio_for_native.dart:84:24)
E/flutter (14805): #3      OpenBalanceController.getOpenBalancePDF (package:otrack/views/reports/controllers/open_balance_controller.dart:143:26)
E/flutter (14805): <asynchronous suspension>
E/flutter (14805): 
E/flutter (14805): #0      DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:643:7)
E/flutter (14805): #1      _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter (14805): #2      _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter (14805): #3      Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter (14805): #4      Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter (14805): #5      Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter (14805): #6      _SyncCompleter._completeError (dart:async/future_impl.dart:51:12)
E/flutter (14805): #7      _Completer.completeError (dart:async/future_impl.dart:23:5)
E/flutter (14805): #8      Future.any.onError (dart:async/future.dart:617:45)
E/flutter (14805): #9      _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter (14805): #10     _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter (14805): #11     Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter (14805): #12     Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter (14805): #13     Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter (14805): #14     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:666:7)
E/flutter (14805): #15     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (14805): #16     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

我的Dio接口代码

Future getOpenBalancePDF() async {
  isLoading.value = true;

  final headers = await BaseClient.generateHeaders();
  Dio dioWithHeaders = Dio(BaseOptions(
      receiveTimeout: 999999, sendTimeout: 999999, headers: headers));
  var dir = await getApplicationDocumentsDirectory();
  String path = "${dir.path}/TransactionSummary.pdf";
  final data = FormData.fromMap({
    "orderType": 0,
    "fromDate": "2000-01-01",
    "toDate": "2023-12-01",
    "customerFilterList": [1387, 1460],
    "exportFormat": 1,
    "openBalance": true
  });
  await dioWithHeaders.download(
    ApiConstants.POST_CUSTOMER_OPEN_BALANCE_REPORT,
    data: data,
    (Headers headers) {
      headers.map.values;
      return path;
    },
  );

  if (path.isNotEmpty) {
    Get.to(
      () => PDFScreen(
        path: path,
      ),
    );
  }
  isLoading.value = false;
}

补充说明

该API在Postman中可正常运行,请求头包含必要鉴权信息,请求体为FormData格式,响应返回PDF文件流。


问题分析与解决方法

核心问题

  1. Dio download方法参数传递错误:download的第二个参数应为文件保存路径,你错误地将data: data作为命名参数传入,且第三个参数的函数不符合onReceiveProgress的签名要求。
  2. 请求方法不匹配:Dio的download方法默认使用GET请求,但你的API需要POST请求(从接口命名及Postman请求方式可判断),GET请求无法携带FormData请求体,导致服务端返回400错误。

修正后的代码

使用post请求获取文件流,再写入本地文件:

Future getOpenBalancePDF() async {
  isLoading.value = true;
  try {
    final headers = await BaseClient.generateHeaders();
    Dio dioWithHeaders = Dio(BaseOptions(
      receiveTimeout: 999999, 
      sendTimeout: 999999, 
      headers: headers
    ));
    var dir = await getApplicationDocumentsDirectory();
    String path = "${dir.path}/TransactionSummary.pdf";
    final data = FormData.fromMap({
      "orderType": 0,
      "fromDate": "2000-01-01",
      "toDate": "2023-12-01",
      "customerFilterList": [1387, 1460],
      "exportFormat": 1,
      "openBalance": true
    });

    // 发送POST请求,以流形式接收响应
    Response response = await dioWithHeaders.post(
      ApiConstants.POST_CUSTOMER_OPEN_BALANCE_REPORT,
      data: data,
      options: Options(responseType: ResponseType.stream),
    );

    // 将响应流写入本地文件
    File file = File(path);
    IOSink sink = file.openWrite();
    await sink.addStream(response.data.stream);
    await sink.close();

    if (await file.exists()) {
      Get.to(() => PDFScreen(path: path));
    }
  } catch (e) {
    // 捕获并处理错误
    print("下载失败: $e");
  } finally {
    isLoading.value = false;
  }
}

额外检查项

  • 确认BaseClient.generateHeaders()生成的请求头与Postman完全一致,特别是Authorization字段。
  • 验证请求体中的参数格式(如日期格式、数组结构)是否与Postman完全匹配,避免因参数类型不匹配被服务端拒绝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:49:59