Reputation: 371
With thwe http package I can send an image to a server by putting te binary data in the body of a post call like in the snippet of this code:
var response = await http.post('My_url', body: File(path).readAsBytesSync(), headers: {
'apikey': 'myAPIKEY',
'Content-Type': 'image/*', // set content-length
});
I can't do the same thing by using Dio, I don't know how to put directly the binary data in the body (like i can do it with postman)
Upvotes: 10
Views: 19305
Reputation: 534
As some people previously commented, dio really is converting to string, and in my case, that was the problem.
As a solution I've replaced the whole request body by uint8List and it worked.
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),
);
Upvotes: 2
Reputation: 11
After combining multiple answers, this solution finally worked for me:
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
));
Upvotes: 1
Reputation: 5392
Anirban Das solutions is working however when I tried to upload 24MB photo file it crashed probably due to
Stream.fromIterable(image.map((e) => [e]))
So instead I tried to directly read file as stream
file.OpenRead()
=> which returns Strea<List<in>>>
accendent or not but upload speed also increased (maybe becase when you map e => [e] it were slowing down sending data) but who know maybe I'm wrong
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
);
Upvotes: 5
Reputation: 1265
I also faced the same you have. In DIO you have to send the binary data through streams. Here is the example how I achieved it,
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
);
Upvotes: 16
Reputation: 17
I kept getting http 403 when using dio package to upload binary data to google storage api. I was able to fix this using :
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',
},
),
);
Upvotes: 0
Reputation: 1260
Just putting my solution if someone stumbles upon the same issue.
I had to upload the file at a signed google storage URL. API required to insert the file binary data in the body of the PUT request. Couldn't implement using the DIO plugin, I resolved the issue using the DART HTTP package, Below is a sample code.
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(),
);
Upvotes: 6
Reputation: 1219
I have declared a FormData object named 'data' and have a map of image with key as filename and value as filepath. 'image' is the key defined on the server side.
data.files.add(MapEntry(
'image',
await MultipartFile.fromFile(image.values.first, filename: "${image.values.first.split("/").last}")
));
Upvotes: 2