[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);
}
}
}
}
我尝试使用的打开 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);
}
}
}
}