Dart Shelf应用读取multipartFormData时遇FormatException问题求助
问题分析与解决
错误原因
服务端统一用readString()读取所有multipart表单内容,但readString()默认以UTF-8编码解析数据。你发送的song.m4a是二进制音频文件,包含大量不符合UTF-8规范的字节,解码时触发FormatException: Missing extension byte(at offset 44)错误。
另外客户端存在冗余操作:已经通过MultipartFile发送了file文件,却又在fields里重复添加'file': 'song.m4a',会导致服务端处理时出现重复字段,容易混淆。
修复方案
1. 客户端代码优化
去掉fields中冗余的file字段,同时不要手动设置Content-Type(MultipartRequest会自动生成带boundary的正确头):
Future<String> sendFile() async { var uri = Uri(scheme: 'https',host: 'localhost',port: 8443, path: '/readSong'); // 创建multipart文件 var myFile = File(filename); var mediaType = MediaType('application', 'octet-stream'); var fileContent = await myFile.readAsBytes(); var multipartFile = http.MultipartFile.fromBytes('file', fileContent, filename: 'mySong.m4a', contentType: mediaType); // 构建multipart请求 var req = http.MultipartRequest('post', uri); req.headers.addAll({ 'company-name': 'myCompany', }); req.fields.addAll({'author': 'meAuthor'}); // 移除冗余的file字段 req.files.add(multipartFile); var response = await req.send(); print(response.toString()); }
2. 服务端代码修复
区分文本字段和文件字段,对二进制文件用readBytes()读取:
dynamic readSong(shelf.Request req) async { final parameters = <String, dynamic>{}; await for (final formData in req.multipartFormData) { if (formData.name == 'file') { // 读取二进制文件数据 final fileBytes = await formData.part.readBytes(); parameters[formData.name] = fileBytes; // 可选:将文件保存到本地 // await File('received_mySong.m4a').writeAsBytes(fileBytes); } else { // 读取文本类型字段 parameters[formData.name] = await formData.part.readString(); } } // 后续业务逻辑处理 return shelf.Response.ok('文件接收完成'); }
内容的提问来源于stack exchange,提问作者Tusshu
相关产品推荐
相关产品推荐

