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

使用Flutter Dio调用文件API时遇406错误的解决与疑问

406错误的根本原因与通用解决办法

根本原因

  1. 自研API的Content-Type校验逻辑:你的API对上传文件的Content-Type存在严格限制,仅接受application/x-tar类型。而Flutter Dio默认会根据文件扩展名推断Content-Type,若其内置的MIME类型映射表中未正确关联.tar文件与application/x-tar,就会发送不符合API要求的Content-Type,触发406错误。
  2. Postman与Dio的MIME推断差异:Postman会自动识别.tar文件并设置正确的application/x-tar类型,而Dio的默认推断规则不匹配API要求,导致请求不被接受。
  3. 406错误的本质误解:虽然406字面意思是服务器无法生成匹配Accept头的响应,但实际场景中是你的API将上传文件的Content-Type纳入了可接受范围校验,后端逻辑把文件类型和请求合法性绑定,导致不符合的请求被拒绝。

通用解决办法

方法一:直接指定单个文件的Content-Type

无需传递冗余的file_tar字段,仅给目标文件字段指定API认可的Content-Type即可:

var dio = Dio();
var formData = FormData.fromMap({
  'file': await MultipartFile.fromFile(
    file.path, 
    contentType: MediaType('application', 'x-tar')
  ),
});
var response = await dio.post(url,
    data: formData,
    options: Options(headers: {
      'Accept': '*/*',
      'Connection': 'keep-alive',
      'Accept-Encoding': 'gzip, deflate, br',
    }), 
    onSendProgress: (int sent, int total) {
      var progress = (sent / total) * 100;
      log('Progress: $progress %');
    });

注意:无需手动设置Content-Type: multipart/form-data,Dio在发送FormData时会自动生成正确的Content-Type(包含boundary),手动设置反而可能导致格式错误。

方法二:扩展Dio的默认MIME类型映射

如果需要上传多种类型文件,不想每次手动指定Content-Type,可以自定义Dio的MIME解析规则:

// 初始化Dio前添加自定义MIME映射
DioMixin.mimeTypeResolver.addResolver((path) {
  if (path.endsWith('.tar')) {
    return MediaType('application', 'x-tar');
  }
  // 可添加其他文件类型的映射,比如.zip
  if (path.endsWith('.zip')) {
    return MediaType('application', 'zip');
  }
  return null; // 未匹配时回退到默认解析逻辑
});

var dio = Dio();
// 后续使用MultipartFile.fromFile时无需手动指定contentType
var formData = FormData.fromMap({
  'file': await MultipartFile.fromFile(file.path),
});

方法三:调整自研API的校验逻辑

如果API不需要严格限制文件Content-Type,可修改后端代码:

  • 忽略文件的Content-Type校验,仅校验文件本身的格式;
  • 允许接收通用二进制类型application/octet-stream,兼容更多客户端的请求。

PHP端解决办法

PHP上传时需确保文件字段携带正确的Content-Type,使用CURL的CURLFile对象指定类型:

$filePath = '/path/to/your/file.tar';
$curlFile = new CURLFile($filePath, 'application/x-tar', 'file');
$postData = ['file' => $curlFile];

$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:12:22