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

