使用 http 包,我可以通过将二进制数据放入 post 调用的正文中来将图像发送到服务器,如以下代码片段所示:
var response = await http.post('My_url', body: File(path).readAsBytesSync(), headers: {
'apikey': 'myAPIKEY',
'Content-Type': 'image/*', // set content-length
});
我不能使用 Dio 做同样的事情,我不知道如何直接将二进制数据放入正文中(就像我可以用 postman 做的那样)
我也遇到和你一样的情况。在 DIO 中,您必须通过流发送二进制数据。这是我如何实现它的示例,
Uint8List image = File(path).readAsBytesSync();
Options options = Options(
contentType: lookupMimeType(path),
headers: {
'Accept': "*/*",
'Content-Length': image.length,
'Connection': 'keep-alive',
'User-Agent': 'ClinicPlush'
}
);
Response response = await dio.put(
url,
data: Stream.fromIterable(image.map((e) => [e])),
options: options
);
如果有人偶然发现同样的问题,只需提出我的解决方案。
我必须通过签名的谷歌存储 URL 上传文件。在 PUT 请求正文中插入文件二进制数据所需的 API。无法使用 DIO 插件实现,我使用 DART HTTP 包解决了该问题,下面是示例代码。
import 'package:http/http.dart' as http;
await http.put(
Uri.parse(uploadURL),
headers: {
'Content-Type': mimeType,
'Accept': "*/*",
'Content-Length': File(filePath).lengthSync().toString(),
'Connection': 'keep-alive',
},
body: File(filePath).readAsBytesSync(),
);
Anirban Das 解决方案正在运行,但是当我尝试上传 24MB 照片文件时,它崩溃了,可能是由于
Stream.fromIterable(image.map((e) => [e]))
所以我尝试直接将文件作为流读取
file.OpenRead()
=> 返回 Strea<List<in>>>
无论是否意外,但上传速度也提高了(也许是因为 你映射 e => [e] 它正在减慢发送数据的速度)但谁知道也许我错了
Uint8List image = File(path).readAsBytesSync();
Options options = Options(
contentType: lookupMimeType(path),
headers: {
'Accept': "*/*",
'Content-Length': image.length,
'Connection': 'keep-alive',
'User-Agent': 'ClinicPlush'
}
);
Response response = await dio.put(
url,
data: file.openRead(), <--- change here
options: options
);
我已经声明了一个名为“data”的 FormData 对象,并且有一个图像映射,其中键作为文件名,值作为文件路径。 'image' 是服务器端定义的键。
data.files.add(MapEntry(
'image',
await MultipartFile.fromFile(image.values.first, filename: "${image.values.first.split("/").last}")
));
当使用 dio 包将二进制数据上传到 google storage api 时,我不断收到 http 403。我能够使用以下方法修复此问题:
Response responseGoogleStorage = await dio.put(
googleStorage.url,
data: File(_imageFile.path).readAsBytesSync(),
options: Options(
headers: {
'Content-Type': contentType,
'Accept': "*/*",
'Content-Length': File(_imageFile.path).lengthSync().toString(),
'Connection': 'keep-alive',
},
),
);
结合多个答案后,这个解决方案终于对我有用:
var len = await image.length();
var response = await dio.put(url,
data: image.openRead(),
options: Options(headers: {
Headers.contentLengthHeader: len,
"Content-Type": "image/jpg",
} // set content-length
));
正如一些人之前评论的那样,dio 确实正在转换为字符串,就我而言,这就是问题所在。
作为解决方案,我已将整个请求正文替换为 uint8List 并且它有效。
final uint8List = file.readAsBytesSync();
await _dio.put(
url,
options: Options(
requestEncoder: (final request, final options) {
return uint8List;
},
headers: {
Headers.contentLengthHeader: '$length',
Headers.contentTypeHeader: contentType,
},
),
data: uint8List,
onSendProgress: (final count, final total) => onProgress(count / total),
);