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

Flutter Web与移动端文件上传报错:Unsupported Operation _Namespace

问题分析与解决方案

错误原因

Web环境下,dart:io的File类并不具备实际的文件系统操作能力,你通过File.fromRawPath创建的对象是无效的,调用readAsBytes()自然会触发Unsupported Operation _Namespace错误。另外,你的createFileFromBytes方法逻辑完全错误——二进制文件(如图片、文档)不能直接转成UTF-8字符串再转回字节,这会彻底损坏文件内容。

修复方案

不需要在Web端强行创建dart:io.File对象,直接保存FilePicker返回的字节数组和文件名即可,上传时分平台处理字节来源:

修改后的完整控制器代码

import 'dart:typed_data';
import 'package:get/get.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';
import 'package:http/http.dart' as http;

class FileUploadController extends GetxController {
  Rx<File?> mobileFile = Rx<File?>(null);
  Rx<Uint8List?> webFileBytes = Rx<Uint8List?>(null);
  String fileName = '';
  var token = 'something';

  void pickFile() async {
    try {
      FilePickerResult? result = await FilePicker.platform.pickFiles(
        allowMultiple: false,
      );

      if (result != null) {
        fileName = result.files.first.name;
        if (kIsWeb) {
          webFileBytes.value = result.files.first.bytes;
          mobileFile.value = null;
        } else {
          mobileFile.value = File(result.files.single.path!);
          webFileBytes.value = null;
        }
      }
    } catch (e) {
      print(e);
    }
  }

  void uploadFile() async {
    try {
      Uint8List? fileBytes;
      // 分平台获取文件字节
      if (kIsWeb) {
        fileBytes = webFileBytes.value;
      } else {
        if (mobileFile.value == null) return;
        fileBytes = await mobileFile.value!.readAsBytes();
      }

      if (fileBytes == null) return;

      Uri uri = Uri.parse('xxxx');
      var request = http.MultipartRequest('POST', uri);

      request.fields.addAll({
        "facility_id": "380",
        "module_id": "1",
        "id": "3263",
      });

      // 直接用字节数组创建MultipartFile
      String fieldName = 'files';
      request.files.add(http.MultipartFile.fromBytes(
        fieldName,
        fileBytes,
        filename: fileName,
      ));

      request.headers.addAll({
        "Authorization": "Bearer $token",
        "Accept": "*/*",
      });
      // 不要手动设置Content-Type和Content-Length,MultipartRequest会自动处理
      // 手动设置会覆盖自动生成的boundary,导致请求格式错误

      var response = await request.send();

      if (response.statusCode == 200) {
        print('文件上传成功!');
      } else {
        print('文件上传失败,状态码:${response.statusCode}');
      }
    } catch (e) {
      print(e);
    }
  }
}

关键修复点

  1. 拆分文件存储:Web端直接保存FilePicker返回的Uint8List,移动端保存File对象,避免跨平台强制兼容dart:io.File。
  2. 移除错误的字节转换逻辑:二进制文件转UTF-8字符串会破坏文件结构,直接使用原始字节数组即可。
  3. 自动处理请求头:MultipartRequest会自动生成包含boundary的Content-Type和正确的Content-Length,手动设置会导致请求格式错误。

内容的提问来源于stack exchange,提问作者who-aditya-nawandar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:23:18