[Flutter Web] 向 API 服务器发送请求 POST 消息的方式有问题吗?

Is there something wrong with the way [Flutter Web] sends a request POST message to the API server?

我尝试使用的打开 api 请求需要内容类型为 multipart/form-data 格式的图像二进制值。 我知道你不能在 flutter web 中使用 dart:io。在查看多个帖子时,我尝试将 multipart/form-data 格式的图像上传到 flutter web 中的 api 服务器。
但是,只出现一条消息,提示无法识别图像。
这是我最后一次尝试在 flutter web 中创建多部分类型。

import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
  PlatformFile? objFile;

  pickImage() async {
    var result = await FilePicker.platform.pickFiles(
      withReadStream: true,
    );
    setState(() {
      objFile = result!.files.single;
    });
    uploadImage();
  }

  uploadImage() async {
    FormData formData = FormData.fromMap({'image' : MultipartFile(test!, objFile!.size, filename: objFile!.name)});
    Dio dio = new Dio();
    var response = await dio.post('API url', data: formData);

  }

我还使用了来自 http 的 Multipart.form 字节,来自 dio 的 Multipart.form 字节。但是结果是一样的。

请求体通过postman拦截器检查的值。

content-type=multipart/form-data;bounary=--dio-boundary-1105759322
----dio-boundary-1105759322
content-disposition: form-data; name="image"; filename="test.jpeg"
content-type: application/octet-stream

ÿØÿÛC


        
%# , #&')*)-0-(0%()(ÿÛC



(((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀŽv"ÿÄÿÄC!1AQaq"‘2¡±#BÁÑR3CðñSbr’á‚Â$&4c“ÿÄÿÄ&!1A2Q"a3BRÿÚ?ù×   „É<$/cŸt8D`aú¦Ä@bálŒZVM„ٔʓTL›eOò¢“
èKÇ(p¢‰¥C’ÄÙ‚Ñx²Ù1Jcœ)B›¢$ ¢‚&
‚7› ˜Žp”{&ÊÀÁAî¤Æ
‚nÈ CØÃêOýÒ›§á$sÊ‚r¡ìLÂ…;"éMI½î«gæV<æ6οÙ%_ƒY®}7Òû€¯MŒ&g¹å|µ£ëÐúc\tÚƵƈúÕ]#kQ‹D/Ÿú·cu9«Hà/¢lÚ–êè·¼&Þt
¯H‚&ɶìÛà®iƒh²SöãÔTs[l›/?[s(’˜¨o€¤Û‹*¥AÖ”ðbUgYR’!äJ!M‹™‹«›î©aÉ*ᕨ4p SÉ…¤)‰ì§=‘âJ» oÙGDRåÌy0—²û r ò€·²?Te8±KSTR8ŹDAååþ7)Oˆk)õ²Qk#Ù€Œ ?DÜû&Ä›„ÍÅ”lQjð¡NÑ%HTWP˜²wýÒc(Ÿð¤ð¢S<*6º>ÊaCœ „Ù0
^J(ª%¢ƒFPm‘^u4^èM‘åL…@#•0Qÿ ºi…32§ÙC•D¿&Èw’ˆº‘Ü"…”<&ýРwP {p ¸DCd¼&ÿ©@¨ˆ› La~¨p¦„)’÷‚ˆº²æÒ›ªĘ̀Šaá€0‹n <ò¦M“YM„    L«=ÕnæÊlªŽÂƒóc„m‚—È™Uó  ªºäªÛ•F†\…}7?¨ªZL`*£è¾ŽÝÌ1¤ÜBúk6­
---------------------------SKIP------------------------------
PTiMÂ!¢(èÊ€YÊÂœ"ÑÂ_T<Ñ5îPp™ð ¨„ôOˤ?¢z\ÂÚ¡½ÐiÊc쨟ÝHŸ¢“3ÝA˜( ‘ÊH›(l€Å¼)Ä‘rEÈ[€‹¬”¼x
W7q?ΣHt®“§¤y\½Ìÿ:ÿÍtÖ§T°AÊÕ\ËZVƒÔPha30%1*¶›Ž!7è¥|f›„îÕQ±„9N6åW,¨^Ù8PHN./Ê€îª2ß*{(l¡™šOU¢Ôå3œ*ꜨŠ‹“3¼$«B*ÌŒS„+EÒ‘Ý VHpV±`²³ó€µgܪ‚#“Ü)À!NPCƒÝIÅԛ–”xý”²™@ ?U‚‹n€å!Œ¦&é*ƒ™¨wÄÖØY¢>«}&ü¢×\Ý?ó*9ç%Òº˜@çò H€¥&ꃒ¤(
‚0O8@@EÎéÊœ@TÕr‚ºT¹ÈÔ7T“2¢ƒœbÅsuOî¶Ô0>‹ŸT|Gô•Óa®ïšÔÇe¤T
he<,¨[ü¶[…·M@ZOˆjtˤÝE© QÿÙ
----dio-boundary-1105759322--

当我使用flutter中使用的MultipartFile.fromFile方法时ios,正常得到响应。所以我很确定 flutter web 设置中一定有一些错误或错误信息。 提前致谢!

这就是我使用 Flutter Web

将图像上传到 Laravel 后端的方法
import 'dart:io';
import 'package:dio/dio.dart' as dio;
import 'package:file_picker/file_picker.dart';

Future pickupUserImage2() async {
    PlatformFile? objFile;
    var picked = await FilePicker.platform.pickFiles();
    objFile = picked!.files.single;
    String? apiUrl = Get.find<MainController>().apiUrl;
    String url = '';
    if (apiUrl != null) url = apiUrl + 'images';
    List<int> list;
    list = List<int>.from(objFile.bytes!);
    dio.FormData formData = dio.FormData.fromMap({'file': dio.MultipartFile.fromBytes(list, filename: objFile.name)});
    DioNetworking _dio = new DioNetworking();

    dynamic result = await _dio.postData(
      url,
      formData,
      contentType: 'multipart/form-data',
    );
    if (result['status'] == true) {
      showToast(result['message']);
      return ImageModel.Image.fromJson(result['data']);
    }
  }

我使用 MultipartFile.fromBytes 添加了一个文件,该文件的第一个参数是我通过此方法创建的列表 "List.from(objFile.bytes!);"

备注:

  • ImageModel.Image是我创建的模型,用来处理图像结果
  • DioNetworking 是一个执行 dio 请求的 class,我只是创建它来执行 身份验证内容
import 'package:dio/dio.dart';
class DioNetworking {
  Dio _dio = new Dio();

Future postData(
    String url,
    dynamic data, {
    String? contentType,
  }) async {

    try {

      Response response = await _dio.post(url,
          data: data,
          options: Options(headers: {
            'content-type': contentType != null ? contentType : 'application/json',
            'Accept': 'application/json',
            // 'Authorization': 'Bearer ${token ?? ''}'
            // other headers
          }));
      if (response.statusCode == 200) {
        dynamic data = response.data;

        return data;
      } else {
        print(response.statusCode);
      }
    } on DioError catch (e) {
      print(e);
      if (e.type == DioErrorType.connectTimeout) {
        return {'status': 'Connect Timed Out'};
      }
      if (e.type == DioErrorType.receiveTimeout) {
        return {'status': 'Receive Timed Out'};
      }
      if (e.type == DioErrorType.response) {
        print(e.response!.data);
        print(e.response!.headers);
      }
    }
  }
}