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

Flutter如何通过multipart请求实现相册多张图片上传至服务端API

Flutter 实现多图选取+Multipart 上传到服务端流程

1. 引入所需依赖

需要用到两个核心库:image_picker 用于相册选图,dio 用于发起网络请求(原生支持Multipart格式,无需手动拼装请求体)。
在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^1.0.4
  dio: ^5.4.0

权限配置

  • 安卓端:在android/app/src/main/AndroidManifest.xml中添加存储读取权限
  • iOS端:在ios/Runner/Info.plist中添加相册访问权限描述NSPhotoLibraryUsageDescription

2. 实现相册多选图片

调用image_picker的多图选择方法,可自行配置压缩参数避免上传文件过大:

import 'package:image_picker/image_picker.dart';
import 'package:dio/dio.dart';
import 'dart:io';

// 存储选中的图片文件
List<XFile> selectedImages = [];

Future<void> pickImages() async {
  final ImagePicker picker = ImagePicker();
  final List<XFile> pickedImages = await picker.pickMultiImage(
    maxWidth: 1080,
    maxHeight: 1080,
    imageQuality: 80, // 图片压缩质量,范围0-100
  );
  if (pickedImages.isNotEmpty) {
    selectedImages = pickedImages;
  }
}

3. 构造Multipart请求上传图片

使用dio的FormData封装请求参数和图片文件,发起POST请求即可:

Future<void> uploadToServer() async {
  if (selectedImages.isEmpty) return;

  final Dio dio = Dio();
  final FormData formData = FormData();

  // 添加所有图片到请求体
  for (int i = 0; i < selectedImages.length; i++) {
    File imgFile = File(selectedImages[i].path);
    formData.files.add(MapEntry(
      // 此处的key需要和后端接口约定的接收字段完全匹配
      'images[$i]',
      await MultipartFile.fromFile(
        imgFile.path,
        // 可选:自定义上传文件名
        filename: 'upload_${DateTime.now().millisecondsSinceEpoch}_$i.png',
      ),
    ));
  }

  // 可选:添加其他表单参数
  formData.fields.addAll([
    const MapEntry('user_id', '123456'),
    const MapEntry('upload_desc', '多图上传测试'),
  ]);

  try {
    final Response response = await dio.post(
      // 替换为你的服务端接口地址
      'https://your-api-domain.com/upload',
      data: formData,
      options: Options(
        contentType: Headers.multipartFormDataContentType,
        // 可选:添加鉴权头
        headers: {'Authorization': 'Bearer your_token'},
      ),
      // 可选:监听上传进度
      onSendProgress: (int sent, int total) {
        print('上传进度:${(sent / total * 100).round()}%');
      },
    );

    if (response.statusCode == 200) {
      // 上传成功的业务逻辑
      print('上传成功:${response.data}');
    }
  } on DioException catch (e) {
    // 异常处理
    print('上传失败:${e.response?.data ?? e.message}');
  }
}

注意事项

  • 若后端约定所有图片使用同一个字段名接收,无需添加下标,直接重复添加同key的文件entry即可:
    for (var img in selectedImages) {
      formData.files.add(MapEntry(
        'images',
        await MultipartFile.fromFile(img.path),
      ));
    }
    
  • 若不使用dio,用Flutter原生http库也可实现,需要手动构造MultipartRequest,逻辑一致但写法更繁琐,优先推荐用dio。
  • 提前申请相册访问权限,避免用户选图时权限被拒导致功能异常。

内容的提问来源于stack exchange,提问作者ARPIT JAISWAL IET Student

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:36:07