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

Flutter中如何从HttpServer请求获取FormData文件?

在Flutter中用dart:io的HttpServer获取FormData上传文件

当你用dart:io创建的HttpServer接收Web端通过FormData上传的文件时,核心是解析multipart/form-data类型的请求,具体步骤如下:

1. 基础请求监听与判断

先启动HttpServer,仅处理POST请求且Content-Type为multipart/form-data的请求:

import 'dart:io';
import 'dart:convert';

void main() async {
  // 提前创建文件保存目录,避免保存时出错
  Directory('./uploads').createSync(recursive: true);
  
  final server = await HttpServer.bind(InternetAddress.anyIPv4, 8080);
  print('服务运行在 ${server.address}:${server.port}');

  await for (var request in server) {
    if (request.method == 'POST' && request.headers.contentType?.mimeType == 'multipart/form-data') {
      await handleFileUpload(request);
    } else {
      request.response.statusCode = HttpStatus.methodNotAllowed;
      await request.response.close();
    }
  }
}

2. 解析Multipart表单并处理文件

使用HttpMultipartFormData解析请求体,区分普通表单字段和文件字段:

Future<void> handleFileUpload(HttpRequest request) async {
  try {
    // 可通过maxSize限制上传文件总大小,示例为10MB
    final formData = await HttpMultipartFormData.parse(request, maxSize: 10 * 1024 * 1024);
    
    await for (var part in formData) {
      if (part.isFile) {
        // 处理上传的文件
        final filePart = part as HttpMultipartFile;
        print('收到文件:${filePart.filename},类型:${filePart.contentType}');
        
        // 给文件名加时间戳,避免同名文件覆盖
        final targetFileName = '${DateTime.now().millisecondsSinceEpoch}_${filePart.filename}';
        final targetFile = File('./uploads/$targetFileName');
        await filePart.openRead().pipe(targetFile.openWrite());
        print('文件已保存至:${targetFile.path}');
      } else {
        // 处理普通表单字段(比如文件描述)
        final fieldValue = await utf8.decodeStream(part);
        print('表单字段 ${part.name} 的值:$fieldValue');
      }
    }

    request.response.statusCode = HttpStatus.ok;
    request.response.write('文件上传成功');
  } catch (e) {
    print('上传错误:$e');
    request.response.statusCode = HttpStatus.internalServerError;
    request.response.write('上传失败:$e');
  } finally {
    await request.response.close();
  }
}

注意事项

  • 必须提前创建文件保存目录,否则会抛出文件不存在的异常
  • 建议对文件名做重命名处理(比如添加时间戳),避免同名文件覆盖
  • 通过maxSize参数限制请求体总大小,防止恶意上传大文件占用资源
  • Web端的fetch请求无需手动设置Content-Type,浏览器会自动添加正确的边界符(boundary)

内容的提问来源于stack exchange,提问作者Sivamani V

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:25:55