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
相关产品推荐
相关产品推荐

