如何在Dart Shelf后端解析前端上传的文件请求?
Shelf后端解析Flutter Multipart文件请求的正确方式
你当前的代码存在两个核心问题:
- 前端用
GET方法发送MultipartRequest:Multipart/form-data类型的请求必须使用POST方法,GET方法不支持这种二进制文件传输格式,会导致后端无法识别请求结构。 - 后端用
readAsString()解析Multipart请求:Multipart请求是分块的二进制格式,不是纯JSON文本,直接读取字符串会导致卡住或解析失败。
第一步:修正前端请求代码
将请求方法改为POST,这是Multipart文件传输的标准方式:
final request = MultipartRequest('POST', Uri.parse('http://192.168.0.8:8080/sendfile')); request.files.add(await MultipartFile.fromPath('fromFilePath', 'file.pdf')); StreamedResponse response = await request.send();
第二步:后端使用shelf_multipart处理Multipart请求
Shelf本身不内置Multipart解析能力,需要借助shelf_multipart包来处理文件上传。
1. 添加依赖
在项目的pubspec.yaml中添加依赖:
dependencies: shelf: ^1.4.0 shelf_multipart: ^1.0.0
2. 解析单个文件的后端代码
import 'package:shelf/shelf.dart'; import 'package:shelf_multipart/shelf_multipart.dart'; FutureOr<Response> fileHandler(Request request) async { try { // 校验请求格式 if (!isMultipartRequest(request)) { return Response.badRequest(body: '请发送Multipart格式的请求'); } // 解析Multipart分块 final parts = await request.multipartParts; for (final part in parts) { // 匹配指定字段名的文件 if (part.name == 'fromFilePath') { // 读取文件字节内容 final fileBytes = await part.readBytes(); // 这里可添加文件保存或业务处理逻辑 // 示例:await File('saved_file.pdf').writeAsBytes(fileBytes); } } return Response.ok('文件接收成功'); } catch (e) { print('解析错误:$e'); return Response.internalServerError(body: '内部服务器错误'); } }
3. 解析多个文件的后端代码
如果前端发送多个文件(无论字段名是否相同),遍历所有分块即可:
import 'package:shelf/shelf.dart'; import 'package:shelf_multipart/shelf_multipart.dart'; FutureOr<Response> fileHandler(Request request) async { try { if (!isMultipartRequest(request)) { return Response.badRequest(body: '请发送Multipart格式的请求'); } final parts = await request.multipartParts; int receivedCount = 0; for (final part in parts) { // 判断当前分块是否为文件 if (part.filename != null) { final fileBytes = await part.readBytes(); // 按原文件名保存或自定义处理 // await File(part.filename!).writeAsBytes(fileBytes); receivedCount++; } } return Response.ok('成功接收$receivedCount个文件'); } catch (e) { print('解析错误:$e'); return Response.internalServerError(body: '内部服务器错误'); } }
内容的提问来源于stack exchange,提问作者Md. Jahid Hasan
相关产品推荐
相关产品推荐

