简体   繁体   English

文件上传适用于 Thunder Client 和 Chrome,但不适用于 Dio 或 MultipartRequest

[英]File upload works in Thunder Client and Chrome, but not Dio or MultipartRequest

I'm trying to create a flutter app that will allow a user to upload an image and a brief description of said image, and if I test my server code with either Thunder Client or Chrome, it works great, but if I try either the MultipartRequest or Dio from a Flutter app, the image seems to be included in the list of text fields, and the "files" part of the form object is empty.我正在尝试创建一个 flutter 应用程序,它允许用户上传图像和所述图像的简短描述,如果我使用 Thunder Client 或 Chrome 测试我的服务器代码,它运行良好,但如果我尝试来自 Flutter 应用程序的 MultipartRequest 或 Dio,图像似乎包含在文本字段列表中, form object 的“文件”部分是空的。 This happens no matter whether I try to upload an image or a small text document.无论我尝试上传图像还是小型文本文档,都会发生这种情况。 Here is my Flutter code:这是我的 Flutter 代码:

ElevatedButton(
  child: const Text("Submit Report"),
  onPressed: () async {
    var dio = Dio();
    var formData = FormData.fromMap({
      "description": "This is a description",
      "location": "This is a location",
      "image": MultipartFile.fromBytes(
          utf8.encode("hello, world"),
          filename: "hello.txt",
          contentType: MediaType("text", "plain")),
    });

    var response = await dio.post(
      "${dotenv.env['SUPABASE_FUNCTIONS_URL']!}/hello-world",
      data: formData,
    );

    debugPrint("***${response.statusCode}***");
  },
)

If I debug and look at the Network tab in Dart's DevTools, I can see the request headers are set like they should be ( Content-Type is multipart/form-data and a boundary is set).如果我调试并查看 Dart 的 DevTools 中的“网络”选项卡,我可以看到请求标头设置得像它们应该的那样( Content-Typemultipart/form-data并且设置了边界)。 My server is just a small Deno function using the multiParser library running on Supabase:我的服务器只是一个小型 Deno function,使用在 Supabase 上运行的 multiParser 库:

serve(async (req) => {
  const form = await multiParser(req);
  console.log(form);

  return new Response(
    JSON.stringify(form),
    { headers: { "Content-Type": "application/json" } },
  );
})

If I look at the invocation logs on Supabase, the requests coming from Thunder Client and Chrome look fine;如果我查看 Supabase 上的调用日志,来自 Thunder Client 和 Chrome 的请求看起来很好; the fields and files are populated the way they should be.字段和文件按应有的方式填充。 Meanwhile, coming from Flutter (Dio and MultipartRequest yield the same result), the console.log(form) from above looks like this:同时,来自 Flutter(Dio 和 MultipartRequest 产生相同的结果),上面的console.log(form)看起来像这样:

{
  fields: {
    description: "This is a description",
    location: "This is a location",
    'image"; filename="hello.txt"\r\ncontent-type: text/plai': "hello, world"
  },
  files: {}
}

I have tried manually setting various headers (like Content-Type ), tried both the MultipartRequest and Dio approaches, and tried manually tweaking the file being uploaded (content type as well as file body).我尝试手动设置各种标头(如Content-Type ),尝试了 MultipartRequest 和 Dio 方法,并尝试手动调整正在上传的文件(内容类型和文件正文)。 Also tried both running in an emulator as well as on a real Android phone.还尝试在模拟器和真正的 Android 手机上运行。 The result is always the same.结果总是一样的。

Used Oak's multipart/form-data parser instead, and it works with everything.改用 Oak 的 multipart/form-data 解析器,它适用于所有内容。 Seems to be some sort of incompatibility between MultipartRequest/Dio and multiParser.似乎是 MultipartRequest/Dio 和 multiParser 之间存在某种不兼容。 Thanks to @pskink for troubleshooting with me.感谢@pskink 与我一起进行故障排除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM