Flutter PUT 来自文件的 HTTP 请求
Posted
技术标签:
【中文标题】Flutter PUT 来自文件的 HTTP 请求【英文标题】:Flutter PUT HTTP request from file 【发布时间】:2020-02-20 02:31:59 【问题描述】:需要帮助解决 Flutter 中的 HTTP 请求,使用 PUT 方法通过 API 将 body 上的图像文件发送到 NextCloud 服务器。
与往常一样,我测试了通过 POSTMAN 发送请求以查看发生了什么。在正文选项卡中选择“二进制”并选择图像文件可以正常工作。
文件按预期存在:
我正在使用以下代码在 Flutter 应用上实现这一点:
_imageFile = 包含来自相机或画廊的图像。
RaisedButton(
color: Colors.blueAccent,
child: Text('enviar'),
onPressed: () async
String base64Image = base64Encode(_imageFile.readAsBytesSync());
print(base64Image);
var client = http.Client();
var request = http.Request(
'PUT', Uri.parse('https://host123.com.br/remote.php/dav/files/82427565709/TOOP.jpeg'));
request.headers.addAll(
HttpHeaders.authorizationHeader: 'Basic ODI0Mjc1NjU3MDk6Y2xlYW5uZXQ=', 'Content-Type': 'image/jpeg');
request.body = base64Image;
var streamedResponse = await client.send(request);
client.close();
print('ok!');
,
),
终端上的结果:
I/flutter ( 8349): /9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAAACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAAAC5JRUMgNjE5NjY
I/flutter ( 8349): ok
通过APP发送到Nextcloud服务器上的结果:
看起来编码或正文上发送的数据有问题。文件“损坏”
两次测试都是同一个文件。
** 更新 **
按照建议将正文数据更改为字节后,不使用 base64 编码。 (下图)
也尝试使用 .toString() 方法进行转换,文件转到服务器但与以前一样,看起来已损坏。
【问题讨论】:
为什么要在发送之前对正文进行 base 64 编码?只需发送字节。 嗨@RichardHeap,将代码更改如下,但“request.body”需要字符串数据类型。将图片添加到原始帖子中。 将字节分配给request.bodyBytes
【参考方案1】:
不需要自己构造请求,因为http包有一个方便的put
方法。此方法(以及更常见的post
方法)采用可选的body
参数,即dynamic
。如果您传递字节,这些字节将逐字发送。如果您传递一个字符串,它将被编码为字节并发送。您还可以将字符串映射传递给将进行表单编码的字符串。
我们可以将您的代码简化为:
var uri = Uri.parse(
'https://host123.com.br/remote.php/dav/files/82427565709/Lowppp.jpeg');
var response = await http.put(
uri,
headers:
HttpHeaders.authorizationHeader: 'Basic xxxxxxx', // insert correct credentials here
'Content-Type': 'image/jpeg',
,
body: await _imageFile.readAsBytes(),
);
print(response.statusCode);
【讨论】:
【参考方案2】:@RichardHeap 帮助找到了解决方案。
需要将正文作为字节发送,而不是作为 bodyBytes request.bodyBytes = imageBytes;
完整的代码工作:
List<int> imageBytes = _imageFile.readAsBytesSync();
var client = http.Client();
var request = http.Request('PUT', Uri.parse('https://host123.com.br/remote.php/dav/files/82427565709/Lowppp.jpeg'));
request.headers.addAll(HttpHeaders.authorizationHeader: 'Basic ODI0Mjc1NjU3MDk6Y2xlYW5uZXQ=', 'Content-Type': 'image/jpeg');
request.bodyBytes = imageBytes;
var streamedResponse = await client.send(request).then((res)
print(res.statusCode);
).catchError((err)
print(err);
);
client.close();
【讨论】:
以上是关于Flutter PUT 来自文件的 HTTP 请求的主要内容,如果未能解决你的问题,请参考以下文章
Angular2 中的 Http PUT 到 .NET Core Web API 提供来自预检请求的 http 401 错误
QNetworkAccessManager HTTP Put 请求不起作用