You need to enable JavaScript to run this app. Flutter安卓应用如何从HttpRequest中获取并存储上传的图片
优惠活动
大模型
产品
解决方案
定价
更多

Flutter安卓应用如何从HttpRequest中获取并存储上传的图片

前置依赖配置

首先在pubspec.yaml中添加两个必要依赖:

dependencies:
  flutter:
    sdk: flutter
  http_parser: ^4.0.2 # 用于解析multipart表单请求
  path_provider: ^2.1.0 # 用于获取应用本地存储路径

添加完成后执行flutter pub get安装依赖。

第一步:修正HTML代码

你现有的文件选择框缺少name属性,表单提交时不会携带上传的文件内容,修改如下:

<form method="post" action="/upload" enctype="multipart/form-data">
    <div>
        <label>Choose images to upload (PNG, JPG)</label>
        <input type="file" name="upload_image" value="Upload File" accept=".jpg, .jpeg, .png">
    </div>
    <div>
        <button>Submit</button>
      </div>
</form>

/upload 路由处理逻辑(含文件解析+本地存储)

首先在代码头部导入需要的包:

import 'dart:io';
import 'package:http_parser/http_parser.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

修改/upload分支的完整处理逻辑:

case '/upload':
  {
    // 仅处理POST请求
    if (body.method != 'POST') {
      body.response.statusCode = HttpStatus.methodNotAllowed;
      body.response.close();
      break;
    }
    
    // 从请求头解析multipart表单的边界值
    final contentType = ContentType.parse(body.headers.contentType.toString());
    final boundary = contentType.parameters['boundary'];
    if (boundary == null) {
      body.response.statusCode = HttpStatus.badRequest;
      body.response.write('无效的请求格式');
      body.response.close();
      break;
    }
    
    // 转换请求流为多部分表单结构
    final parts = body.transform(MimeMultipartTransformer(boundary));
    await for (final part in parts) {
      // 只处理对应HTML中name为upload_image的文件字段
      final contentDisposition = part.headers['content-disposition'];
      if (contentDisposition == null || !contentDisposition.contains('name="upload_image"')) {
        continue;
      }
      
      // 解析原始文件名,未获取到则用时间戳生成默认文件名
      final fileNameMatch = RegExp(r'filename="([^"]+)"').firstMatch(contentDisposition);
      final fileName = fileNameMatch?.group(1) ?? '${DateTime.now().millisecondsSinceEpoch}.jpg';
      
      // 获取应用私有文档目录,其他应用无法访问该目录内容
      final appDir = await getApplicationDocumentsDirectory();
      final saveDirPath = path.join(appDir.path, 'uploaded_images');
      // 确保存储目录存在
      await Directory(saveDirPath).create(recursive: true);
      final fullSavePath = path.join(saveDirPath, fileName);
      
      // 将文件流写入本地存储
      final targetFile = File(fullSavePath);
      await targetFile.openWrite().addStream(part);
      
      // 此处可将fullSavePath存入本地列表/数据库,方便后续应用内加载展示
    }
    
    body.response.statusCode = 201;
    body.response.write('上传成功');
    body.response.close();
  }
  break;

应用内查看图片说明

所有上传的图片默认存储在应用文档目录/uploaded_images路径下,你可以遍历该目录下的所有文件,使用Flutter内置的Image.file(File(图片完整路径))组件直接渲染展示。

注意:你当前绑定的服务IP是191.168.1.120,通常家用局域网网段为192.168开头,如果测试时无法访问服务,请检查IP配置是否正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 14:15:01