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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:55:18