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

Flutter中如何将图片文件传入POST类型HTTP请求的Body中

问题原因及修复方案

存在的问题

  • 冗余的File构造逻辑:ImagePicker返回的selectedImage本身就是合法的File对象,不需要再通过Uri.parse+File.fromUri二次构造,路径含特殊字符时很容易触发解析异常
  • 未读取响应体:jsonResponse变量未赋值就直接传入解析方法,即便请求成功也会触发崩溃
  • 无空值校验:直接用image!强制拆包,若image为null会直接抛出空异常
  • 无异常捕获逻辑:网络请求、文件读取、响应解析的异常都未捕获,无法定位具体报错原因
  • MultipartFile构造方式繁琐:不需要手动读取文件字节,直接用fromPath构造稳定性更高

修复后的代码

import 'dart:convert';
import 'package:flutter/foundation.dart';

Future<void> SaveCustomTestBooking() async {
  // 前置参数校验
  if (EncUserId.isEmpty || image == null) {
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("必要参数缺失,请选择图片后重试")));
    return;
  }
  try {
    var postUri = Uri.parse("http://medbo.digitalicon.in/api/medboapi/SaveCustomTestBooking");
    var request = http.MultipartRequest('POST', postUri);
    request.fields['VisitDate'] = _selectedDate;
    request.fields['EncUserId'] = EncUserId;
    // 直接用文件路径构造MultipartFile
    request.files.add(await http.MultipartFile.fromPath(
      'image', 
      image!.path,
      contentType: MediaType('image', 'jpeg'),
    ));

    // 等待请求返回,增加超时限制
    final streamedResponse = await request.send().timeout(const Duration(seconds: 15));
    // 读取响应体内容
    final responseStr = await streamedResponse.stream.bytesToString();
    // 打印返回信息方便调试
    debugPrint("请求状态码:${streamedResponse.statusCode},返回内容:$responseStr");

    if (streamedResponse.statusCode == 200) {
      print("Uploaded!");
      // 解析响应数据
      final jsonResponse = json.decode(responseStr);
      Navigator.push(context,MaterialPageRoute(builder: (context) => DieticianAfterDateSelectPage(
        rresponse: DieticianEncBookingIdModel.fromJson(jsonResponse),
      )));
    } else {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("请求失败,状态码:${streamedResponse.statusCode}")));
      throw Exception("请求失败:$responseStr");
    }
  } catch (e) {
    // 捕获所有异常并提示具体错误
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("操作出错:${e.toString()}")));
    rethrow;
  }
}

额外注意点

  • 安卓9及以上版本默认禁止HTTP请求,要么将接口换成HTTPS,要么在安卓配置文件中添加该域名的HTTP放行规则
  • 确保已经在AndroidManifest.xml和Info.plist中配置了存储读取、网络访问权限
  • 如果允许上传png等其他格式图片,不要固定写死contentType为jpeg,可以根据文件后缀动态判断类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:39:04